Skip to content

Commit d7e7f22

Browse files
authored
[Clang] fix missing source location for errors in macro-expanded (llvm#143460)
Fixes llvm#143216 --- This patch fixes diagnostic locations for tokens from macro expansions.
1 parent f39f53e commit d7e7f22

File tree

7 files changed

+49
-7
lines changed

7 files changed

+49
-7
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ Bug Fixes in This Version
694694
- Constant evaluation now correctly runs the destructor of a variable declared in
695695
the second clause of a C-style ``for`` loop. (#GH139818)
696696
- Fixed a bug with constexpr evaluation for structs containing unions in case of C++ modules. (#GH143168)
697+
- Fixed incorrect token location when emitting diagnostics for tokens expanded from macros. (#GH143216)
697698

698699
Bug Fixes to Compiler Builtins
699700
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/include/clang/Parse/Parser.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,7 @@ class Parser : public CodeCompletionHandler {
290290
return ConsumeToken();
291291
}
292292

293-
SourceLocation getEndOfPreviousToken() {
294-
return PP.getLocForEndOfToken(PrevTokLocation);
295-
}
293+
SourceLocation getEndOfPreviousToken() const;
296294

297295
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
298296
/// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)

clang/lib/Parse/ParseExprCXX.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier(
421421
// like we never saw it.
422422
Token Identifier = Tok; // Stash away the identifier.
423423
ConsumeToken(); // Eat the identifier, current token is now '::'.
424-
Diag(PP.getLocForEndOfToken(ConsumeToken()), diag::err_expected)
425-
<< tok::identifier;
424+
ConsumeToken();
425+
Diag(getEndOfPreviousToken(), diag::err_expected) << tok::identifier;
426426
UnconsumeToken(Identifier); // Stick the identifier back.
427427
Next = NextToken(); // Point Next at the '{' token.
428428
}

clang/lib/Parse/ParseStmt.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -832,10 +832,13 @@ StmtResult Parser::ParseCaseStatement(ParsedStmtContext StmtCtx,
832832
<< "'case'" << tok::colon
833833
<< FixItHint::CreateReplacement(ColonLoc, ":");
834834
} else {
835-
SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
835+
SourceLocation ExpectedLoc = getEndOfPreviousToken();
836+
836837
Diag(ExpectedLoc, diag::err_expected_after)
837838
<< "'case'" << tok::colon
838-
<< FixItHint::CreateInsertion(ExpectedLoc, ":");
839+
<< FixItHint::CreateInsertion(ExpectedLoc,
840+
tok::getTokenName(tok::colon));
841+
839842
ColonLoc = ExpectedLoc;
840843
}
841844

clang/lib/Parse/Parser.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1873,6 +1873,11 @@ Parser::TryAnnotateName(CorrectionCandidateCallback *CCC,
18731873
return AnnotatedNameKind::Unresolved;
18741874
}
18751875

1876+
SourceLocation Parser::getEndOfPreviousToken() const {
1877+
SourceLocation TokenEndLoc = PP.getLocForEndOfToken(PrevTokLocation);
1878+
return TokenEndLoc.isValid() ? TokenEndLoc : Tok.getLocation();
1879+
}
1880+
18761881
bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
18771882
assert(Tok.isNot(tok::identifier));
18781883
Diag(Tok, diag::ext_keyword_as_ident)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s
2+
3+
namespace GH143216 {
4+
#define A x y
5+
enum { A }; // expected-error {{missing ',' between enumerators}}
6+
7+
#define B x y
8+
void f() {
9+
int a[2];
10+
auto [B] = a; // expected-error {{expected ','}}
11+
}
12+
13+
#define C <int!
14+
template <class T> class D;
15+
D C; // expected-error {{expected unqualified-id}} \
16+
// expected-error {{expected '>'}} \
17+
// expected-note {{to match this '<'}}
18+
19+
#define E F::{
20+
class F { E }}; // expected-error {{expected identifier}} \
21+
// expected-error {{expected member name or ';' after declaration specifiers}}
22+
}

clang/test/Parser/switch-recovery.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,3 +229,16 @@ void fn1() {
229229
}
230230
} // expected-error{{expected statement}}
231231
}
232+
233+
namespace GH143216 {
234+
#define FOO 1 case 3:
235+
236+
int f(int x) {
237+
switch (x) {
238+
case FOO // expected-error {{expected ':' after 'case'}}
239+
return 0;
240+
default:
241+
return 1;
242+
}
243+
}
244+
}

0 commit comments

Comments
 (0)