Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
4 changes: 1 addition & 3 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Parse/ParseExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
}
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/Parse/ParseStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
11 changes: 11 additions & 0 deletions clang/lib/Parse/Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1873,6 +1873,17 @@ Parser::TryAnnotateName(CorrectionCandidateCallback *CCC,
return AnnotatedNameKind::Unresolved;
}

SourceLocation Parser::getEndOfPreviousToken() const {
SourceLocation TokenEndLoc = PP.getLocForEndOfToken(PrevTokLocation);
if (TokenEndLoc.isValid())
return TokenEndLoc;

if (Tok.getLocation().isMacroID())
return PP.getSourceManager().getSpellingLoc(Tok.getLocation());

return Tok.getLocation();
}

bool Parser::TryKeywordIdentFallback(bool DisableKeyword) {
assert(Tok.isNot(tok::identifier));
Diag(Tok, diag::ext_keyword_as_ident)
Expand Down
20 changes: 20 additions & 0 deletions clang/test/Parser/macro-expansion-recovery.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s

namespace GH143216 {
#define A x y // expected-error {{missing ',' between enumerators}}
enum { A };

#define B x y // expected-error {{expected ','}}
void f() {
int a[2];
auto [B] = a;
}

#define C <int! // expected-error {{expected '>'}}
template <class T> class D;
D C; // expected-error {{expected unqualified-id}} \
// expected-note {{to match this '<'}}

#define E F::{ // expected-error {{expected identifier}}
class F { E }}; // expected-error {{expected member name or ';' after declaration specifiers}}
}
13 changes: 13 additions & 0 deletions clang/test/Parser/switch-recovery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
return 0;
default:
return 1;
}
}
}