Skip to content

Commit 7ff507f

Browse files
committed
Diagnose incorrect syntax for #pragma clang diagnostic
We would previously fail to diagnose unexpected tokens after a 'push' or 'pop' directive. Fixes #13920
1 parent f686e4b commit 7ff507f

File tree

3 files changed

+19
-2
lines changed

3 files changed

+19
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,9 @@ Improvements to Clang's diagnostics
366366
been fixed and the Fix-It now only spans to the end of the ``:``.
367367
- Clang now underlines the parameter list of function declaration when emitting
368368
a note about the mismatch in the number of arguments.
369+
- Clang now diagnoses unexpected tokens after a
370+
``#pragma clang|GCC diagnostic push|pop`` directive.
371+
(`#13920: <https://github.com/llvm/llvm-project/issues/13920>`_)
369372

370373
Bug Fixes in This Version
371374
-------------------------

clang/lib/Lex/Pragma.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,16 +1291,26 @@ struct PragmaDiagnosticHandler : public PragmaHandler {
12911291
IdentifierInfo *II = Tok.getIdentifierInfo();
12921292
PPCallbacks *Callbacks = PP.getPPCallbacks();
12931293

1294+
// Get the next token, which is either an EOD or a string literal. We lex
1295+
// it now so that we can early return if the previous token was push or pop.
1296+
PP.LexUnexpandedToken(Tok);
1297+
12941298
if (II->isStr("pop")) {
12951299
if (!PP.getDiagnostics().popMappings(DiagLoc))
12961300
PP.Diag(Tok, diag::warn_pragma_diagnostic_cannot_pop);
12971301
else if (Callbacks)
12981302
Callbacks->PragmaDiagnosticPop(DiagLoc, Namespace);
1303+
1304+
if (Tok.isNot(tok::eod))
1305+
PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
12991306
return;
13001307
} else if (II->isStr("push")) {
13011308
PP.getDiagnostics().pushMappings(DiagLoc);
13021309
if (Callbacks)
13031310
Callbacks->PragmaDiagnosticPush(DiagLoc, Namespace);
1311+
1312+
if (Tok.isNot(tok::eod))
1313+
PP.Diag(Tok.getLocation(), diag::warn_pragma_diagnostic_invalid_token);
13041314
return;
13051315
}
13061316

@@ -1316,9 +1326,8 @@ struct PragmaDiagnosticHandler : public PragmaHandler {
13161326
return;
13171327
}
13181328

1319-
PP.LexUnexpandedToken(Tok);
1329+
// At this point, we expect a string literal.
13201330
SourceLocation StringLoc = Tok.getLocation();
1321-
13221331
std::string WarningName;
13231332
if (!PP.FinishLexStringLiteral(Tok, WarningName, "pragma diagnostic",
13241333
/*AllowMacroExpansion=*/false))

clang/test/Preprocessor/pragma_diagnostic.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
// expected-warning@-2 {{unknown warning group '-Winvalid-name', ignored}}
3535
#endif
3636

37+
// From GH13920
38+
#pragma clang diagnostic push ignored "-Wdeprecated-declarations" // expected-warning {{unexpected token in pragma diagnostic}}
39+
#pragma clang diagnostic pop ignored "-Wdeprecated-declarations" // expected-warning {{unexpected token in pragma diagnostic}}
40+
41+
3742
// Testing pragma clang diagnostic with -Weverything
3843
void ppo(void){} // First test that we do not diagnose on this.
3944

0 commit comments

Comments
 (0)