From 4d494e76d098fde0a3399f792f360c111e546ae8 Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Sat, 29 Jul 2023 16:05:46 +0200 Subject: [PATCH] [Clang] Handle static_assert messages with an expression started by a literal Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D156597 --- clang/lib/Parse/ParseDeclCXX.cpp | 19 ++++++++++++++++--- clang/test/SemaCXX/static-assert-cxx26.cpp | 9 +++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index c1e09db2b3ee..e4a10f2e5c98 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1016,10 +1016,23 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) { return nullptr; } - if (isTokenStringLiteral()) - AssertMessage = ParseUnevaluatedStringLiteralExpression(); - else if (getLangOpts().CPlusPlus26) + bool ParseAsExpression = false; + if (getLangOpts().CPlusPlus26) { + for (unsigned I = 0;; ++I) { + const Token &T = GetLookAheadToken(I); + if (T.is(tok::r_paren)) + break; + if (T.isNot(tok::string_literal)) { + ParseAsExpression = true; + break; + } + } + } + + if (ParseAsExpression) AssertMessage = ParseConstantExpressionInExprEvalContext(); + else if (isTokenStringLiteral()) + AssertMessage = ParseUnevaluatedStringLiteralExpression(); else { Diag(Tok, diag::err_expected_string_literal) << /*Source='static_assert'*/ 1; diff --git a/clang/test/SemaCXX/static-assert-cxx26.cpp b/clang/test/SemaCXX/static-assert-cxx26.cpp index 4c28fba1ca5f..c2bb2d2ebc6f 100644 --- a/clang/test/SemaCXX/static-assert-cxx26.cpp +++ b/clang/test/SemaCXX/static-assert-cxx26.cpp @@ -65,6 +65,10 @@ struct string_view { } }; +constexpr string_view operator+(auto, string_view S) { + return S; +} + constexpr const char g_[] = "long string"; template @@ -79,6 +83,11 @@ struct array { }; static_assert(false, string_view("test")); // expected-error {{static assertion failed: test}} +static_assert(false, "Literal" + string_view("test")); // expected-error {{static assertion failed: test}} +static_assert(false, L"Wide Literal" + string_view("test")); // expected-error {{static assertion failed: test}} +static_assert(false, "Wild" "Literal" "Concatenation" + string_view("test")); // expected-error {{static assertion failed: test}} +static_assert(false, "Wild" "Literal" L"Concatenation" + string_view("test")); // expected-error {{static assertion failed: test}} +static_assert(false, "Wild" u"Literal" L"Concatenation" + string_view("test")); // expected-error {{unsupported non-standard concatenation of string literals}} static_assert(false, string_view("😀")); // expected-error {{static assertion failed: 😀}} static_assert(false, string_view(0, nullptr)); // expected-error {{static assertion failed:}} static_assert(false, string_view(1, "ABC")); // expected-error {{static assertion failed: A}}