Author: Oleksandr T. Date: 2025-06-11T14:19:25-07:00 New Revision: d7e7f22626f214766f3592341dd1737fd232c6a5
URL: https://github.com/llvm/llvm-project/commit/d7e7f22626f214766f3592341dd1737fd232c6a5 DIFF: https://github.com/llvm/llvm-project/commit/d7e7f22626f214766f3592341dd1737fd232c6a5.diff LOG: [Clang] fix missing source location for errors in macro-expanded (#143460) Fixes #143216 --- This patch fixes diagnostic locations for tokens from macro expansions. Added: clang/test/Parser/macro-expansion-recovery.cpp Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Parse/Parser.h clang/lib/Parse/ParseExprCXX.cpp clang/lib/Parse/ParseStmt.cpp clang/lib/Parse/Parser.cpp clang/test/Parser/switch-recovery.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8043ab48f0b4f..b42d5f8425af6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -694,6 +694,7 @@ Bug Fixes in This Version - Constant evaluation now correctly runs the destructor of a variable declared in the second clause of a C-style ``for`` loop. (#GH139818) - Fixed a bug with constexpr evaluation for structs containing unions in case of C++ modules. (#GH143168) +- Fixed incorrect token location when emitting diagnostics for tokens expanded from macros. (#GH143216) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 0b2fab4a45c96..d99de77a52919 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -290,9 +290,7 @@ class Parser : public CodeCompletionHandler { return ConsumeToken(); } - SourceLocation getEndOfPreviousToken() { - return PP.getLocForEndOfToken(PrevTokLocation); - } + SourceLocation getEndOfPreviousToken() const; /// GetLookAheadToken - This peeks ahead N tokens and returns that token /// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1) diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index d95260829e4a0..55ad7f256fa82 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -421,8 +421,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier( // like we never saw it. Token Identifier = Tok; // Stash away the identifier. ConsumeToken(); // Eat the identifier, current token is now '::'. - Diag(PP.getLocForEndOfToken(ConsumeToken()), diag::err_expected) - << tok::identifier; + ConsumeToken(); + Diag(getEndOfPreviousToken(), diag::err_expected) << tok::identifier; UnconsumeToken(Identifier); // Stick the identifier back. Next = NextToken(); // Point Next at the '{' token. } diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index c788723023c8b..c00759893b0c4 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -832,10 +832,13 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx, << "'case'" << tok::colon << FixItHint::CreateReplacement(ColonLoc, ":"); } else { - SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation); + SourceLocation ExpectedLoc = getEndOfPreviousToken(); + Diag(ExpectedLoc, diag::err_expected_after) << "'case'" << tok::colon - << FixItHint::CreateInsertion(ExpectedLoc, ":"); + << FixItHint::CreateInsertion(ExpectedLoc, + tok::getTokenName(tok::colon)); + ColonLoc = ExpectedLoc; } diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index db65c05cc114a..788ed79e0c1fa 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1873,6 +1873,11 @@ Parser::TryAnnotateName(CorrectionCandidateCallback *CCC, return AnnotatedNameKind::Unresolved; } +SourceLocation Parser::getEndOfPreviousToken() const { + SourceLocation TokenEndLoc = PP.getLocForEndOfToken(PrevTokLocation); + return TokenEndLoc.isValid() ? TokenEndLoc : Tok.getLocation(); +} + bool Parser::TryKeywordIdentFallback(bool DisableKeyword) { assert(Tok.isNot(tok::identifier)); Diag(Tok, diag::ext_keyword_as_ident) diff --git a/clang/test/Parser/macro-expansion-recovery.cpp b/clang/test/Parser/macro-expansion-recovery.cpp new file mode 100644 index 0000000000000..6826cc04e4df5 --- /dev/null +++ b/clang/test/Parser/macro-expansion-recovery.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +namespace GH143216 { +#define A x y +enum { A }; // expected-error {{missing ',' between enumerators}} + +#define B x y +void f() { + int a[2]; + auto [B] = a; // expected-error {{expected ','}} +} + +#define C <int! +template <class T> class D; +D C; // expected-error {{expected unqualified-id}} \ + // expected-error {{expected '>'}} \ + // expected-note {{to match this '<'}} + +#define E F::{ +class F { E }}; // expected-error {{expected identifier}} \ + // expected-error {{expected member name or ';' after declaration specifiers}} +} diff --git a/clang/test/Parser/switch-recovery.cpp b/clang/test/Parser/switch-recovery.cpp index baf703cd03aed..7b3909e3b0d32 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: + +int f(int x) { + switch (x) { + case FOO // expected-error {{expected ':' after 'case'}} + return 0; + default: + return 1; + } +} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits