mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
More const modification detection. Grab the version number into CMake.
This commit is contained in:
@@ -1,10 +1,24 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
project(c3c)
|
||||
|
||||
# Grab the version
|
||||
file(READ "src/version.h" ver)
|
||||
if (NOT ${ver} MATCHES "COMPILER_VERSION \"([0-9]+.[0-9]+.[0-9]+)\"")
|
||||
message(FATAL_ERROR "Compiler version could not be parsed from version.h")
|
||||
endif()
|
||||
|
||||
# Set the project and version
|
||||
project(c3c VERSION ${CMAKE_MATCH_1})
|
||||
message("C3C version: ${CMAKE_PROJECT_VERSION}")
|
||||
|
||||
# Enable fetching (for Windows)
|
||||
include(FetchContent)
|
||||
include(FeatureSummary)
|
||||
|
||||
|
||||
set(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
|
||||
set(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
|
||||
|
||||
# We use C11 and C++17
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
|
||||
@@ -1237,17 +1237,25 @@ static inline bool sema_call_check_contract_param_match(SemaContext *context, De
|
||||
SEMA_ERROR(expr, "You may not pass null to a '&' parameter.");
|
||||
return false;
|
||||
}
|
||||
if (expr->expr_kind == EXPR_UNARY && expr->unary_expr.expr->expr_kind == EXPR_IDENTIFIER)
|
||||
{
|
||||
if (expr->unary_expr.expr->identifier_expr.decl->var.kind == VARDECL_CONST && param->var.out_param)
|
||||
{
|
||||
SEMA_ERROR(expr, "A const parameter may not be passed into a function or macro as an 'out' argument.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (expr->expr_kind != EXPR_IDENTIFIER) return true;
|
||||
Decl *ident = expr->identifier_expr.decl;
|
||||
if (ident->decl_kind != DECL_VAR) return true;
|
||||
if (ident->var.out_param && param->var.in_param)
|
||||
{
|
||||
SEMA_ERROR(expr, "It's not allowed to pass an 'out' parameter into a function or macro as an 'in' argument.");
|
||||
SEMA_ERROR(expr, "An 'out' parameter may not be passed into a function or macro as an 'in' argument.");
|
||||
return false;
|
||||
}
|
||||
if (ident->var.in_param && param->var.out_param)
|
||||
{
|
||||
SEMA_ERROR(expr, "It's not allowed to pass an 'in' parameter into a function or macro as an 'out' argument.");
|
||||
SEMA_ERROR(expr, "An 'in' parameter may not be passed into a function or macro as an 'out' argument.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.100"
|
||||
#define COMPILER_VERSION "0.4.101"
|
||||
36
test/test_suite/contracts/constant_out.c3
Normal file
36
test/test_suite/contracts/constant_out.c3
Normal file
@@ -0,0 +1,36 @@
|
||||
module test;
|
||||
|
||||
|
||||
struct Abc
|
||||
{
|
||||
int a;
|
||||
}
|
||||
|
||||
fn void Abc.update(Abc* a, int ab)
|
||||
{
|
||||
a.a = ab;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param [out] a
|
||||
**/
|
||||
fn void Abc.update_fail(Abc* a, int ab)
|
||||
{
|
||||
a.a = ab;
|
||||
}
|
||||
|
||||
const Abc X = { 2 };
|
||||
|
||||
|
||||
fn int main()
|
||||
{
|
||||
const Abc Y = { 3 };
|
||||
int* z = &X.a;
|
||||
*z = 31;
|
||||
X.update(1);
|
||||
X.update_fail(2); // #error: const parameter may not
|
||||
X.a = 32; // #error: cannot assign to a constant
|
||||
Y.a = 34; // #error: cannot assign to a constant
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ fn void bar(Foo* f)
|
||||
**/
|
||||
fn void foo(Foo* f)
|
||||
{
|
||||
bar(f); // #error: It's not allowed to pass an 'in'
|
||||
bar(f); // #error: macro as an 'out' argument
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,5 +27,5 @@ fn void foo2(Foo* f)
|
||||
**/
|
||||
fn void baz(Foo *f)
|
||||
{
|
||||
foo2(f); // #error: It's not allowed to pass an 'out'
|
||||
foo2(f); // #error: may not be passed into a function
|
||||
}
|
||||
Reference in New Issue
Block a user