https://github.com/a-tarasyuk created https://github.com/llvm/llvm-project/pull/143460
Fixes #143216 --- This patch addresses the issue where diagnostics for `case` statements originating from macro expansions lacked source location information when the colon `:` was missing. >From dd4953312066cb63ae1a3882270426c87b1f5b7a Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Tue, 10 Jun 2025 02:47:51 +0300 Subject: [PATCH] [Clang] fix missing source location for ':' error in macro-expanded case statements --- clang/docs/ReleaseNotes.rst | 1 + clang/include/clang/Basic/DiagnosticCommonKinds.td | 1 + clang/lib/Parse/ParseStmt.cpp | 14 ++++++++++++++ clang/test/Parser/switch-recovery.cpp | 13 +++++++++++++ 4 files changed, 29 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 322686fce0b04..0ecbb4864050c 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -689,6 +689,7 @@ Bug Fixes in This Version - Fixed type mismatch error when 'builtin-elementwise-math' arguments have different qualifiers, this should be well-formed. (#GH141397) - Constant evaluation now correctly runs the destructor of a variable declared in the second clause of a C-style ``for`` loop. (#GH139818) +- Fixed incorrect diagnostic location for missing ``:`` in case statements expanded from macros. (#GH143216) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 0bd8a423c393e..ee8fc66c1822c 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -83,6 +83,7 @@ let CategoryName = "Parse Issue" in { def err_expected : Error<"expected %0">; def err_expected_either : Error<"expected %0 or %1">; def err_expected_after : Error<"expected %1 after %0">; +def note_macro_expansion : Note<"expanded from macro '%0'">; def err_param_redefinition : Error<"redefinition of parameter %0">; def warn_method_param_redefinition : Warning<"redefinition of method parameter %0">; diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index c788723023c8b..5db6dd36f840b 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -833,9 +833,23 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, << FixItHint::CreateReplacement(ColonLoc, ":"); } else { SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation); + SourceLocation ExprLoc = + LHS.get() ? LHS.get()->getExprLoc() : SourceLocation(); + + if (ExpectedLoc.isInvalid() && ExprLoc.isMacroID()) { + ExpectedLoc = PP.getSourceManager().getSpellingLoc(ExprLoc); + } + Diag(ExpectedLoc, diag::err_expected_after) << "'case'" << tok::colon << FixItHint::CreateInsertion(ExpectedLoc, ":"); + + if (ExprLoc.isMacroID()) { + Diag(ExprLoc, diag::note_macro_expansion) + << Lexer::getImmediateMacroNameForDiagnostics( + ExprLoc, PP.getSourceManager(), getLangOpts()); + } + ColonLoc = ExpectedLoc; } diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp index baf703cd03aed..5966b04b3f636 100644 --- a/clang/test/Parser/switch-recovery.cpp +++ b/clang/test/Parser/switch-recovery.cpp @@ -229,3 +229,16 @@ void fn1() { } } // expected-error{{expected statement}} } + +namespace GH143216 { +#define FOO 1 case 3: // expected-error {{expected ':' after 'case'}} + +int f(int x) { + switch (x) { + case FOO // expected-note {{expanded from macro 'FOO'}} + return 0; + default: + return 1; + } +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits