Author: Yihan Wang
Date: 2026-10-21T13:46:55+08:00
New Revision: 9e013a240337f6b01241af4884ddbea9213f06fa

URL: 
https://github.com/llvm/llvm-project/commit/9e013a240337f6b01241af4884ddbea9213f06fa
DIFF: 
https://github.com/llvm/llvm-project/commit/9e013a240337f6b01241af4884ddbea9213f06fa.diff

LOG: [clang][Lex] Fix crash on pragma annotations in preprocessor expressions 
(#232413)

Reject annotation tokens before accessing `IdentifierInfo`, emitting the
existing invalid-token diagnostic instead of asserting.

```cpp
#define M _Pragma("pack(push, 1)")
#if (0 + M 1)
#endif
```

https://godbolt.org/z/sqjs9nPrj

Assisted by Codex.

---------

Signed-off-by: yronglin <[email protected]>
Co-authored-by: Ambrose Leeb <[email protected]>

Added: 
    clang/test/Preprocessor/expr-pragma.c

Modified: 
    clang/docs/ReleaseNotes.md
    clang/lib/Lex/PPExpressions.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 830109b8c4a39..138d6fad0ad1f 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -1075,6 +1075,7 @@ features cannot lower the translation-unit ABI level;
 
 #### Miscellaneous Clang Crashes Fixed
 
+- 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
   source file. (#GH222310)

diff  --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index eb614cba959a4..731ee036f7262 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -248,7 +248,10 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, 
DefinedTracker &DT,
     // If this token's spelling is a pp-identifier, check to see if it is
     // 'defined' or if it is a macro.  Note that we check here because many
     // keywords are pp-identifiers, so we can't check the kind.
-    if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
+    // Pragma operators can produce annotation tokens, which have no
+    // IdentifierInfo and should be diagnosed as invalid expression tokens.
+    if (!PeekTok.isAnnotation() && PeekTok.getIdentifierInfo()) {
+      IdentifierInfo *II = PeekTok.getIdentifierInfo();
       // Handle "defined X" and "defined(X)".
       if (II->isStr("defined"))
         return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP);

diff  --git a/clang/test/Preprocessor/expr-pragma.c 
b/clang/test/Preprocessor/expr-pragma.c
new file mode 100644
index 0000000000000..a5934a07d6602
--- /dev/null
+++ b/clang/test/Preprocessor/expr-pragma.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -fms-extensions -verify 
-verify-ignore-unexpected=note %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -fms-extensions -verify 
-verify-ignore-unexpected=note %s
+
+// Use -fsyntax-only so pragma handlers can produce annotation tokens.
+#define M _Pragma("pack(push, 1)")
+
+#if (0 + M 1) // expected-error {{invalid token at start of a preprocessor 
expression}}
+#endif
+
+#if _Pragma("pack(push, 1)") 1 // expected-error {{invalid token at start of a 
preprocessor expression}}
+#endif
+
+#if 0
+#elif M 1 // expected-error {{invalid token at start of a preprocessor 
expression}}
+#endif
+
+#if !M 1 // expected-error {{invalid token at start of a preprocessor 
expression}}
+#endif
+
+#if 0 && M 1 // expected-error {{invalid token at start of a preprocessor 
expression}}
+#endif
+
+#if (0 + __pragma(pack(push, 1)) 1) // expected-error {{invalid token at start 
of a preprocessor expression}}
+#endif


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to