mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
Improve error when trying to use an extern const as a compile time constant. #2969
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
- Constdef declarations introduced.
|
||||
- Properly support `@deprecated` as contract.
|
||||
- Support deprecating enum values.
|
||||
- Improve error when trying to use an extern const as a compile time constant. #2969
|
||||
|
||||
### Stdlib changes
|
||||
- Summarize sort macros as generic function wrappers to reduce the amount of generated code. #2831
|
||||
|
||||
@@ -4707,6 +4707,20 @@ static bool sema_analyse_variable_type(SemaContext *context, Type *type, SourceS
|
||||
UNREACHABLE
|
||||
}
|
||||
|
||||
INLINE void sema_error_not_constant(SemaContext *context, Decl *target, Expr *init)
|
||||
{
|
||||
if (init->expr_kind == EXPR_IDENTIFIER)
|
||||
{
|
||||
Decl *decl = init->ident_expr;
|
||||
if (decl->decl_kind == DECL_VAR && decl->var.kind == VARDECL_CONST && decl->is_extern)
|
||||
{
|
||||
SEMA_ERROR(init, "%s must be assigned a compile-time constant. 'extern' constants are resolved at link time and therefore are not compile-time values.", target->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
SEMA_ERROR(init, "Expected a compile time constant value assigned to %s.", target->name);
|
||||
|
||||
}
|
||||
/**
|
||||
* Analyse $foo and $Foo variables.
|
||||
*/
|
||||
@@ -4792,7 +4806,7 @@ bool sema_analyse_var_decl_ct(SemaContext *context, Decl *decl, bool *check_defi
|
||||
if (!expr_is_runtime_const(init))
|
||||
{
|
||||
if (check_defined) goto FAIL_CHECK;
|
||||
SEMA_ERROR(init, "Expected a constant expression assigned to %s.", decl->name);
|
||||
sema_error_not_constant(context, decl, init);
|
||||
goto FAIL;
|
||||
}
|
||||
break;
|
||||
@@ -4811,7 +4825,7 @@ bool sema_analyse_var_decl_ct(SemaContext *context, Decl *decl, bool *check_defi
|
||||
if (!expr_is_runtime_const(init))
|
||||
{
|
||||
if (check_defined) goto FAIL_CHECK;
|
||||
SEMA_ERROR(init, "Expected a constant expression assigned to %s.", decl->name);
|
||||
sema_error_not_constant(context, decl, init);
|
||||
goto FAIL;
|
||||
}
|
||||
// Update the type.
|
||||
|
||||
@@ -1679,7 +1679,15 @@ static bool sema_analyse_parameter(SemaContext *context, Expr *arg, Decl *param,
|
||||
{
|
||||
RETURN_SEMA_FUNC_ERROR(definition, arg, "This method is only valid on a compile time constant value.");
|
||||
}
|
||||
RETURN_SEMA_FUNC_ERROR(definition, arg, "A compile time parameter must always be a constant, did you mistake it for a normal parameter?");
|
||||
if (arg->expr_kind == EXPR_IDENTIFIER)
|
||||
{
|
||||
Decl *decl = arg->ident_expr;
|
||||
if (decl->decl_kind == DECL_VAR && decl->var.kind == VARDECL_CONST && decl->is_extern)
|
||||
{
|
||||
RETURN_SEMA_FUNC_ERROR(definition, arg, "A compile-time parameter requires a value known at compile time. Did you mistake if for a regular parameter? 'extern' constants are not compile-time constants.");
|
||||
}
|
||||
}
|
||||
RETURN_SEMA_FUNC_ERROR(definition, arg, "A compile time parameter must always be a compile-time constant value, did you mistake it for a regular parameter?");
|
||||
}
|
||||
break;
|
||||
case VARDECL_PARAM_CT_TYPE:
|
||||
|
||||
16
test/test_suite/compile_time/extern_is_not_const.c3
Normal file
16
test/test_suite/compile_time/extern_is_not_const.c3
Normal file
@@ -0,0 +1,16 @@
|
||||
module test;
|
||||
import std;
|
||||
|
||||
extern const void* FOO @cname("malloc");
|
||||
|
||||
macro foo($x) {}
|
||||
|
||||
fn void test()
|
||||
{
|
||||
var $x = FOO; // #error: $x must be assigned a compile-time constant. 'extern' constants are resolved
|
||||
}
|
||||
|
||||
fn void test2()
|
||||
{
|
||||
foo(FOO); // #error: $x must be assigned a compile-time constant. 'extern' constants are resolved
|
||||
}
|
||||
Reference in New Issue
Block a user