https://github.com/ipranjalks created https://github.com/llvm/llvm-project/pull/238342
`PragmaWarningHandler` and `PragmaExecCharsetHandler` lex their arguments with `PP.Lex(Tok)`, which expands macros and `_Pragma` / `_pragma` operators. When an expanded pragma operator produces an annotation token (such as `tok::annot_pragma_pack`), calling `Tok.getIdentifierInfo()` triggers an assertion failure (`!isAnnotation() && "getIdentifierInfo() on an annotation token!"`). Guard `Tok.getIdentifierInfo()` with `Tok.isAnnotation()` so Clang emits the existing invalid-specifier warning instead of crashing. Assisted-by: Gemini >From 1a1f99d9e966d49e20f0e6ea7282ae5adf34114a Mon Sep 17 00:00:00 2001 From: Pranjal Srivastava <[email protected]> Date: Tue, 3 Nov 2026 13:40:05 +0000 Subject: [PATCH] Fix crash on pragma annotations --- clang/docs/ReleaseNotes.md | 2 ++ clang/lib/Lex/Pragma.cpp | 6 +++--- clang/test/Preprocessor/pragma_microsoft.c | 14 ++++++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 743c1ead8ec789..e7ca82763558ef 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -1189,6 +1189,8 @@ documentation](CIR/index.md) for more information regarding ClangIR's status and #### Miscellaneous Clang Crashes Fixed +- Fixed a crash in `#pragma warning` and `#pragma execution_character_set` when + containing an annotation-producing `_Pragma` or `__pragma`. - Fixed a crash in preprocessor conditionals containing `_Pragma`. - Fixed a crash when Microsoft extensions were enabled and an unterminated `__identifier` expression reached the end of a preprocessing directive or diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index 078842ab08c5ef..f088cdc4765d7a 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -1453,7 +1453,7 @@ struct PragmaWarningHandler : public PragmaHandler { } PP.Lex(Tok); - IdentifierInfo *II = Tok.getIdentifierInfo(); + IdentifierInfo *II = Tok.isAnnotation() ? nullptr : Tok.getIdentifierInfo(); if (II && II->isStr("push")) { // #pragma warning( push[ ,n ] ) @@ -1484,7 +1484,7 @@ struct PragmaWarningHandler : public PragmaHandler { // #pragma warning( warning-specifier : warning-number-list // [; warning-specifier : warning-number-list...] ) while (true) { - II = Tok.getIdentifierInfo(); + II = Tok.isAnnotation() ? nullptr : Tok.getIdentifierInfo(); if (!II && !Tok.is(tok::numeric_constant)) { PP.Diag(Tok, diag::warn_pragma_warning_spec_invalid); return; @@ -1601,7 +1601,7 @@ struct PragmaExecCharsetHandler : public PragmaHandler { } PP.Lex(Tok); - IdentifierInfo *II = Tok.getIdentifierInfo(); + IdentifierInfo *II = Tok.isAnnotation() ? nullptr : Tok.getIdentifierInfo(); if (II && II->isStr("push")) { // #pragma execution_character_set( push[ , string ] ) diff --git a/clang/test/Preprocessor/pragma_microsoft.c b/clang/test/Preprocessor/pragma_microsoft.c index 0140672d9cb5e6..1f2519bf564588 100644 --- a/clang/test/Preprocessor/pragma_microsoft.c +++ b/clang/test/Preprocessor/pragma_microsoft.c @@ -256,3 +256,17 @@ void pragma_optimize_foo() { #pragma execution_character_set(push, "utf-8") #pragma execution_character_set(push, "UTF-8") #pragma execution_character_set(pop) + +#define PRAGMA_PACK _Pragma("pack(push, 1)") +#pragma warning(PRAGMA_PACK) // expected-warning {{expected 'push', 'pop', 'default', 'disable', 'error', 'once', 'suppress', 1, 2, 3, or 4}} \ + // expected-error {{expected identifier or '('}} +; +#pragma warning(disable : 4705 ; PRAGMA_PACK) // expected-warning {{expected 'push', 'pop', 'default', 'disable', 'error', 'once', 'suppress', 1, 2, 3, or 4}} \ + // expected-error {{expected identifier or '('}} +; +#pragma execution_character_set(PRAGMA_PACK) // expected-warning {{expected 'push' or 'pop'}} \ + // expected-error {{expected identifier or '('}} +; +__pragma(warning(_Pragma("pack(push, 1)"))) // expected-warning {{expected 'push', 'pop', 'default', 'disable', 'error', 'once', 'suppress', 1, 2, 3, or 4}} +__pragma(warning(disable : 4705 ; _Pragma("pack(push, 1)"))) // expected-warning {{expected 'push', 'pop', 'default', 'disable', 'error', 'once', 'suppress', 1, 2, 3, or 4}} +__pragma(execution_character_set(_Pragma("pack(push, 1)"))) // expected-warning {{expected 'push' or 'pop'}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
