From e9ec421b3b4a74c42dab45e71c7cda03dab164ef Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 6 Oct 2025 00:31:27 +0200 Subject: [PATCH] Compiler fails to stop error print in recursive macro, and also prints unnecessary "inline at" #2513. --- releasenotes.md | 1 + src/compiler/sema_stmts.c | 2 ++ src/compiler/semantic_analyser.c | 4 +++- test/test_suite/macros/macro_recursive_err.c3 | 12 ++++++++++++ test/test_suite/macros/macro_recursive_err2.c3 | 12 ++++++++++++ test/test_suite/macros/macro_untyped_varargs.c3 | 15 +++++++++++++++ 6 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/test_suite/macros/macro_recursive_err.c3 create mode 100644 test/test_suite/macros/macro_recursive_err2.c3 diff --git a/releasenotes.md b/releasenotes.md index 105816245..5a36d8c5f 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -7,6 +7,7 @@ ### Fixes - Bug in `io::write_using_write_byte`. - Bitstruct value cannot be used to index a const array in compile time. #2512 +- Compiler fails to stop error print in recursive macro, and also prints unnecessary "inline at" #2513. ### Stdlib changes diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index cedd7a120..373797f04 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -2339,6 +2339,8 @@ static inline bool sema_analyse_compound_statement_no_scope(SemaContext *context { ast_poison(ast); all_ok = false; + // Don't continue inside a macro, since we get too many "inlined" errors. + if (context->current_macro) break; } } AstId *next = ast ? &ast_last(ast)->next : &compound_statement->compound_stmt.first_stmt; diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index 7676e9dce..7b251d6ef 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -584,11 +584,13 @@ void sema_print_inline(SemaContext *context, SourceSpan original) { if (!context) return; InliningSpan *inlined_at = context->inlined_at; + SourceSpan last_span = INVALID_SPAN; while (inlined_at) { - if (inlined_at->span.a != original.a) + if (inlined_at->span.a != original.a && inlined_at->span.a != last_span.a) { sema_note_prev_at(inlined_at->span, "Inlined from here."); + last_span = inlined_at->span; } inlined_at = inlined_at->prev; } diff --git a/test/test_suite/macros/macro_recursive_err.c3 b/test/test_suite/macros/macro_recursive_err.c3 new file mode 100644 index 000000000..87a77393e --- /dev/null +++ b/test/test_suite/macros/macro_recursive_err.c3 @@ -0,0 +1,12 @@ +import std; + +macro @_macro(#i) +{ + if (#i == 0) { return; } + return @_macro(#i - 1); // #error: Failure evaluating macro, max call depth reached +} + +fn void main() +{ + @_macro(1); +} diff --git a/test/test_suite/macros/macro_recursive_err2.c3 b/test/test_suite/macros/macro_recursive_err2.c3 new file mode 100644 index 000000000..299cd3c25 --- /dev/null +++ b/test/test_suite/macros/macro_recursive_err2.c3 @@ -0,0 +1,12 @@ +import std; + +macro @_macro(#i) +{ + if (#i == 0) { return; } + return @_macro(--#i); // #error: You cannot assign to a constant expression +} + +fn void main() +{ + @_macro(1); +} \ No newline at end of file diff --git a/test/test_suite/macros/macro_untyped_varargs.c3 b/test/test_suite/macros/macro_untyped_varargs.c3 index fd3984f6f..6628f3215 100644 --- a/test/test_suite/macros/macro_untyped_varargs.c3 +++ b/test/test_suite/macros/macro_untyped_varargs.c3 @@ -1,9 +1,21 @@ macro foo(...) { $vaarg["hello"]; // #error: Expected the argument index here +} + +macro foo_a(...) +{ int x; $vaarg[x]; // #error: Vararg functions need a constant argument +} + +macro foo_b(...) +{ $vaarg[-1]; // #error: negative +} + +macro foo_c(...) +{ $vaarg[100]; // #error: varargs exist } @@ -22,4 +34,7 @@ fn void main() int x; foo2(x); // #error: This argument needs to be a compile time constant foo3(3); // #error: The argument was not a type. + foo_a(1, -1, 3141, 999 + 1); + foo_b(1, -1, 3141, 999 + 1); + foo_c(1, -1, 3141, 999 + 1); }