From 9c435352b99267524396839bc83e396768ed72fb Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Tue, 20 Jan 2026 17:12:41 +0100 Subject: [PATCH] - Second value in switch range not checked properly, causing an error on non-const values. #2777 --- releasenotes.md | 1 + src/compiler/sema_stmts.c | 6 +++--- .../statements/ranged_switch_with_non_const_end.c3 | 10 ++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 test/test_suite/statements/ranged_switch_with_non_const_end.c3 diff --git a/releasenotes.md b/releasenotes.md index 5c4b880cd..0eacde3ee 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -21,6 +21,7 @@ - Create optional with `~` instead of `?`. `return io::EOF?;` becomes `return io::EOF~`. - Deprecated use of `?` to create optional. - Vectors not converted to arrays when passed as raw vaargs. #2776 +- Second value in switch range not checked properly, causing an error on non-const values. #2777 ### Fixes - Regression with npot vector in struct triggering an assert #2219. diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index a02b73c3b..737e41c58 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -2432,10 +2432,10 @@ static inline bool sema_check_value_case(SemaContext *context, Type *switch_type *if_chained = true; return true; } - if (is_range && !first_is_const) + if (is_range) { - sema_error_at(context, extend_span_with_token(expr->span, to_expr->span), "Ranges must be constant integers."); - return false; + bool second_is_const = sema_cast_const(to_expr) && (expr_is_const_int(to_expr) || expr_is_const_enum(to_expr)); + if (!first_is_const || !second_is_const) RETURN_SEMA_ERROR(first_is_const ? to_expr : expr, "Ranges must be constant integers or enum values, but this is not an integer / enum constant."); } bool is_enum = expr_is_const_enum(expr); ExprConst *const_expr = &expr->const_expr; diff --git a/test/test_suite/statements/ranged_switch_with_non_const_end.c3 b/test/test_suite/statements/ranged_switch_with_non_const_end.c3 new file mode 100644 index 000000000..0e7de4e57 --- /dev/null +++ b/test/test_suite/statements/ranged_switch_with_non_const_end.c3 @@ -0,0 +1,10 @@ +fn void main() +{ + for (int i = 0; ; ) + { + switch (i) + { + case 4 .. i: // #error: Ranges must be constant integers or enum values, but this is not an integer + } + } +} \ No newline at end of file