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

Reply via email to