[clang] [Clang] fix parser recovery for invalid static_assert string messages (PR #187859)
Oleksandr Tarasiuk via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 27 06:26:03 PDT 2026
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/187859
>From 9c9141f638b53d7c9127919e20786e27fc92012c Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Sat, 21 Mar 2026 14:24:49 +0200
Subject: [PATCH 1/2] [Clang] fix parser recovery for invalid static_assert
string messages
---
clang/docs/ReleaseNotes.rst | 1 +
clang/lib/Parse/ParseDeclCXX.cpp | 13 ++++++++-----
clang/test/Parser/static_assert.cpp | 16 +++++++++++-----
3 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 45234c316eba8..fb674faa42006 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -339,6 +339,7 @@ Bug Fixes in This Version
- Fixed a crash when normalizing constraints involving concept template parameters whose index coincided with non-concept template parameters in the same parameter mapping.
- Fixed a crash caused by accessing dependent diagnostics of a non-dependent context.
- Fixed a crash when substituting into a non-type template parameter that has a type containing an undeduced placeholder type.
+- 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 274c354d59808..f942edbb8f596 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -990,11 +990,13 @@ 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();
+ 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 if (tokenIsLikeStringLiteral(Tok, getLangOpts()))
AssertMessage = ParseUnevaluatedStringLiteralExpression();
else {
@@ -1010,7 +1012,8 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
}
}
- if (T.consumeClose())
+ bool StopAt = Tok.isNot(tok::r_paren);
+ if (T.consumeClose() || StopAt)
return nullptr;
DeclEnd = Tok.getLocation();
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, ""
>From b56527df8825122a57e8aeab24a3946ac7ab4b17 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Sun, 26 Apr 2026 15:25:37 +0300
Subject: [PATCH 2/2] fix parser recovery for invalid static_assert message
---
clang/lib/Parse/ParseDeclCXX.cpp | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index c230e7b6c8317..7ead704b6f8cd 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -996,10 +996,13 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
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()))
+ } else if (tokenIsLikeStringLiteral(Tok, getLangOpts())) {
AssertMessage = ParseUnevaluatedStringLiteralExpression();
- else {
+ } else {
Diag(Tok, diag::err_expected_string_literal)
<< /*Source='static_assert'*/ 1;
SkipMalformedDecl();
@@ -1012,9 +1015,7 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
}
}
- bool StopAt = Tok.isNot(tok::r_paren);
- if (T.consumeClose() || StopAt)
- return nullptr;
+ T.consumeClose();
DeclEnd = Tok.getLocation();
ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert, TokName);
More information about the cfe-commits
mailing list