From 5a36f0bc166634dfca5fa26ad92648df821b9cdd Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sat, 18 Jan 2025 22:40:58 +0100 Subject: [PATCH] Fix issue with `@const` where the statement `$foo = 1;` was not considered constant. --- releasenotes.md | 1 + src/compiler/sema_const.c | 2 +- src/compiler/sema_decls.c | 18 +++++++++++++++- test/test_suite/compile_time/concat_const.c3 | 22 ++++++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 test/test_suite/compile_time/concat_const.c3 diff --git a/releasenotes.md b/releasenotes.md index 6c9076577..dddf9c7f4 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -10,6 +10,7 @@ - Fix bug in SHA1 for longer blocks #1854. - Fix lack of location for reporting lambdas with missing return statement #1857. - Compiler allows a generic module to be declared with different parameters #1856. +- Fix issue with `@const` where the statement `$foo = 1;` was not considered constant. ### Stdlib changes - Added '%h' and '%H' for printing out binary data in hexadecimal using the formatter. diff --git a/src/compiler/sema_const.c b/src/compiler/sema_const.c index b2cd1faec..4a455b402 100644 --- a/src/compiler/sema_const.c +++ b/src/compiler/sema_const.c @@ -319,7 +319,7 @@ bool sema_expr_analyse_ct_concat(SemaContext *context, Expr *concat_expr, Expr * if (!sema_analyse_expr(context, left)) return false; if (!sema_cast_const(left)) RETURN_SEMA_ERROR(left, "Expected this to evaluate to a constant value."); if (!sema_analyse_expr(context, right)) return false; - if (!sema_cast_const(right)) RETURN_SEMA_ERROR(left, "Expected this to evaluate to a constant value."); + if (!sema_cast_const(right)) RETURN_SEMA_ERROR(right, "Expected this to evaluate to a constant value."); Type *element_type = left->type->canonical; Type *right_type = right->type->canonical; switch (left->const_expr.const_kind) diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index edeadd8ef..08e0f6212 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -3829,6 +3829,23 @@ static inline bool sema_analyse_macro(SemaContext *context, Decl *decl, bool *er if (body->next) RETURN_SEMA_ERROR(body, "There should not be any statements after 'return'."); body = NULL; continue; + case AST_EXPR_STMT: + // For some cases we KNOW it's not correct. + switch (body->expr_stmt->expr_kind) + { + case EXPR_IDENTIFIER: + case EXPR_LAMBDA: + case EXPR_FORCE_UNWRAP: + case EXPR_ASM: + case EXPR_EXPR_BLOCK: + case EXPR_TERNARY: + case EXPR_RETHROW: + break; + default: + body = astptrzero(body->next); + continue; + } + FALLTHROUGH; case AST_POISONED: case AST_ASM_STMT: case AST_ASM_LABEL: @@ -3840,7 +3857,6 @@ static inline bool sema_analyse_macro(SemaContext *context, Decl *decl, bool *er case AST_CONTINUE_STMT: case AST_DEFAULT_STMT: case AST_DEFER_STMT: - case AST_EXPR_STMT: case AST_FOR_STMT: case AST_FOREACH_STMT: case AST_IF_CATCH_SWITCH_STMT: diff --git a/test/test_suite/compile_time/concat_const.c3 b/test/test_suite/compile_time/concat_const.c3 new file mode 100644 index 000000000..88766eeb0 --- /dev/null +++ b/test/test_suite/compile_time/concat_const.c3 @@ -0,0 +1,22 @@ +module wi3enrich; +import std::io; +import std::os::env; + +macro String to_string(uint $num) @const +{ + char[] $res; + int $i = 0; + $for (;$num != 0;) + $res = $res +++ (char) ('0' + $num % 10); + $num = $num / 10; + $i++; + $endfor + $res = $res +++ '\0'; + return (String) $res; +} + +fn int main(String[] args) +{ + io::printn(to_string(4)); + return 0; +}