[clang] [clang][lex] Fix lexing malformed pragma within include directive (PR #138165)

Stefan Weigl-Bosker via cfe-commits cfe-commits at lists.llvm.org
Fri May 2 13:19:46 PDT 2025


https://github.com/sweiglbosker updated https://github.com/llvm/llvm-project/pull/138165

>From 08f13cc755539516c2a5606ed0a7dfa20b99bbd3 Mon Sep 17 00:00:00 2001
From: Stefan Weigl-Bosker <stefan at s00.xyz>
Date: Thu, 1 May 2025 12:24:17 -0400
Subject: [PATCH] [Lex] fix lexing malformed pragma within include directive

---
 clang/docs/ReleaseNotes.rst                  | 4 +++-
 clang/lib/Lex/Pragma.cpp                     | 4 ++--
 clang/test/Preprocessor/_Pragma-in-include.c | 4 ++++
 3 files changed, 9 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Preprocessor/_Pragma-in-include.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 1dd97bcc67364..943aff772b08b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -535,7 +535,9 @@ Bug Fixes in This Version
 - Fixed visibility calculation for template functions. (#GH103477)
 - Fixed a bug where an attribute before a ``pragma clang attribute`` or
   ``pragma clang __debug`` would cause an assertion. Instead, this now diagnoses
-  the invalid attribute location appropriately.  (#GH137861)
+  the invalid attribute location appropriately. (#GH137861)
+- Fixed a crash when a malformed ``_Pragma`` directive appears as part of an 
+  ``#include`` directive. (#GH138094)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
index 5b6a29bdad910..01c85e6ad95d5 100644
--- a/clang/lib/Lex/Pragma.cpp
+++ b/clang/lib/Lex/Pragma.cpp
@@ -220,11 +220,11 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
   if (!tok::isStringLiteral(Tok.getKind())) {
     Diag(PragmaLoc, diag::err__Pragma_malformed);
     // Skip bad tokens, and the ')', if present.
-    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof))
+    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eof) && Tok.isNot(tok::eod))
       Lex(Tok);
     while (Tok.isNot(tok::r_paren) &&
            !Tok.isAtStartOfLine() &&
-           Tok.isNot(tok::eof))
+           Tok.isNot(tok::eof) && Tok.isNot(tok::eod))
       Lex(Tok);
     if (Tok.is(tok::r_paren))
       Lex(Tok);
diff --git a/clang/test/Preprocessor/_Pragma-in-include.c b/clang/test/Preprocessor/_Pragma-in-include.c
new file mode 100644
index 0000000000000..6a121946bf0ce
--- /dev/null
+++ b/clang/test/Preprocessor/_Pragma-in-include.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -E %s -verify
+
+// Don't crash, verify that diagnostics are preserved
+#include _Pragma( // expected-error {{_Pragma takes a parenthesized string literal}} expected-error {{expected "FILENAME"}} 



More information about the cfe-commits mailing list