[clang] d7e7f22 - [Clang] fix missing source location for errors in macro-expanded (#143460)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 11 14:19:29 PDT 2025
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;
+ }
+}
+}
More information about the cfe-commits
mailing list