[clang] 5ee1495 - [Clang] fix parser recovery for invalid static_assert string messages (#187859)

via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 27 07:19:32 PDT 2026


Author: Oleksandr Tarasiuk
Date: 2026-04-27T17:19:27+03:00
New Revision: 5ee1495ab6529ba2ae8d4af98d5c42ab96d3441d

URL: https://github.com/llvm/llvm-project/commit/5ee1495ab6529ba2ae8d4af98d5c42ab96d3441d
DIFF: https://github.com/llvm/llvm-project/commit/5ee1495ab6529ba2ae8d4af98d5c42ab96d3441d.diff

LOG: [Clang] fix parser recovery for invalid static_assert string messages (#187859)

Fixes #187690

--- 

This PR fixes parser recovery for invalid `static_assert` declarations
with string literal messages. The parser now stops the message lookahead
on `;` and `eof`, so invalid inputs are diagnosed as parse errors.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Parse/ParseDeclCXX.cpp
    clang/test/Parser/static_assert.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b766bb834cf4f..760d91fd97914 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -507,6 +507,7 @@ Bug Fixes in This Version
 - Fixed a crash when assigning to an element of an ``ext_vector_type`` with ``bool`` element type. (#GH189260)
 - Clang now emits an error for friend declarations of lambda members. (#GH26540)
 - Fixed a crash caused by lambda capture handling in delayed default arguments. (#GH176534)
+- Fixed a crash when parsing invalid ``static_assert`` declarations with string-literal messages (#GH187690).
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index d1e2e2c2c6ce1..c1fcde8f46c1c 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -990,14 +990,19 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
     }
 
     if (ParseAsExpression) {
-      Diag(Tok,
-           getLangOpts().CPlusPlus26
-               ? diag::warn_cxx20_compat_static_assert_user_generated_message
-               : diag::ext_cxx_static_assert_user_generated_message);
       AssertMessage = ParseConstantExpressionInExprEvalContext();
-    } else if (tokenIsLikeStringLiteral(Tok, getLangOpts()))
+      if (Tok.is(tok::r_paren)) {
+        Diag(Tok,
+             getLangOpts().CPlusPlus26
+                 ? diag::warn_cxx20_compat_static_assert_user_generated_message
+                 : diag::ext_cxx_static_assert_user_generated_message);
+      } else {
+        T.consumeClose();
+        return nullptr;
+      }
+    } else if (tokenIsLikeStringLiteral(Tok, getLangOpts())) {
       AssertMessage = ParseUnevaluatedStringLiteralExpression();
-    else {
+    } else {
       Diag(Tok, diag::err_expected_string_literal)
           << /*Source='static_assert'*/ 1;
       SkipMalformedDecl();
@@ -1010,8 +1015,7 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
     }
   }
 
-  if (T.consumeClose())
-    return nullptr;
+  T.consumeClose();
 
   DeclEnd = Tok.getLocation();
   ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);

diff  --git a/clang/test/Parser/static_assert.cpp b/clang/test/Parser/static_assert.cpp
index 4fe7d3cda7b21..928948c418ade 100644
--- a/clang/test/Parser/static_assert.cpp
+++ b/clang/test/Parser/static_assert.cpp
@@ -1,6 +1,12 @@
-// RUN: %clang_cc1 -fsyntax-only -triple=x86_64-linux -std=c++2a -verify=cxx2a %s
-// RUN: %clang_cc1 -fsyntax-only -triple=x86_64-linux -std=c++2c -verify=cxx2c %s
+// RUN: %clang_cc1 -fsyntax-only -triple=x86_64-linux -verify %s
 
-static_assert(true, "" // cxx2a-warning {{'static_assert' with a user-generated message is a C++26 extension}} \
-                       // cxx2a-note {{to match this '('}} cxx2c-note {{to match this '('}}
-                       // cxx2a-error {{expected ')'}}     cxx2c-error {{expected ')'}}
+// expected-error at +2 {{expected ')'}}
+// expected-note at +1 {{to match this '('}}
+static_assert(true, ""1);
+
+// expected-error at +1 {{unexpected ';' before ')'}}
+static_assert(true, "";);
+
+// expected-error at +2 {{expected ')'}}
+// expected-note at +1 {{to match this '('}}
+static_assert(true, ""


        


More information about the cfe-commits mailing list