[clang] [Clang][Parser] Accept P2741R3 (static_assert with user-generated message) in C++11 as an extension (PR #102044)
Mital Ashok via cfe-commits
cfe-commits at lists.llvm.org
Tue Aug 6 10:07:57 PDT 2024
https://github.com/MitalAshok updated https://github.com/llvm/llvm-project/pull/102044
>From 90441c251c1ec5a3b8be923ca9678c8d3d586bee Mon Sep 17 00:00:00 2001
From: Mital Ashok <mital at mitalashok.co.uk>
Date: Mon, 5 Aug 2024 20:29:12 +0100
Subject: [PATCH 1/8] [Clang][Sema] Backport P2741R3 (static_assert with
user-generated message) to C++11
---
clang/docs/LanguageExtensions.rst | 2 ++
.../clang/Basic/DiagnosticParseKinds.td | 6 ++++
clang/lib/Frontend/InitPreprocessor.cpp | 6 ++--
clang/lib/Parse/ParseDeclCXX.cpp | 10 +++++--
clang/test/Lexer/cxx-features.cpp | 2 +-
clang/test/SemaCXX/static-assert-ext.cpp | 28 +++++++++++++++++++
6 files changed, 46 insertions(+), 8 deletions(-)
create mode 100644 clang/test/SemaCXX/static-assert-ext.cpp
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index be07f81cc41b0..5953ca5259da2 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1483,6 +1483,7 @@ Generic lambda expressions __cpp_generic_lambdas C+
variable templates __cpp_variable_templates C++14 C++03
Binary literals __cpp_binary_literals C++14 C++03
Relaxed constexpr __cpp_constexpr C++14 C++11
+Static assert with no message __cpp_static_assert>=201411L C++17 C++11
Pack expansion in generalized lambda-capture __cpp_init_captures C++17 C++03
``if constexpr`` __cpp_if_constexpr C++17 C++11
fold expressions __cpp_fold_expressions C++17 C++03
@@ -1503,6 +1504,7 @@ Conditional ``explicit`` __cpp_conditional_explicit C+
``static operator()`` __cpp_static_call_operator C++23 C++03
Attributes on Lambda-Expressions C++23 C++11
Attributes on Structured Bindings __cpp_structured_bindings C++26 C++03
+Static assert with user-generated message __cpp_static_assert>=202306L C++26 C++11
Pack Indexing __cpp_pack_indexing C++26 C++03
``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03
-------------------------------------------- -------------------------------- ------------- -------------
diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index f8d50d12bb935..eaad99451eb7f 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -470,6 +470,12 @@ def warn_c17_compat_static_assert_no_message : Warning<
"'_Static_assert' with no message is incompatible with C standards before "
"C23">,
DefaultIgnore, InGroup<CPre23Compat>;
+def ext_cxx_static_assert_user_generated_message : ExtWarn<
+ "'static_assert' with a user-generated message is a C++26 extension">,
+ InGroup<CXX26>;
+def warn_cxx20_compat_static_assert_user_generated_message : Warning<
+ "'static_assert' with a user-generated message is incompatible with "
+ "C++ standards before C++26">, DefaultIgnore, InGroup<CXXPre26Compat>;
def err_function_definition_not_allowed : Error<
"function definition is not allowed here">;
def err_expected_end_of_enumerator : Error<
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 8e62461d8a181..038fad5272be7 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -671,10 +671,8 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
LangOpts.CPlusPlus23 ? "202211L"
: LangOpts.CPlusPlus17 ? "201603L"
: "200907");
- Builder.defineMacro("__cpp_static_assert", LangOpts.CPlusPlus26 ? "202306L"
- : LangOpts.CPlusPlus17
- ? "201411L"
- : "200410");
+ // C++17 / C++26 static_assert backported
+ Builder.defineMacro("__cpp_static_assert", "202306L");
Builder.defineMacro("__cpp_decltype", "200707L");
Builder.defineMacro("__cpp_attributes", "200809L");
Builder.defineMacro("__cpp_rvalue_references", "200610L");
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index aac89d910bbc8..87ba660c35b55 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -1073,7 +1073,7 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
}
bool ParseAsExpression = false;
- if (getLangOpts().CPlusPlus26) {
+ if (getLangOpts().CPlusPlus11) {
for (unsigned I = 0;; ++I) {
const Token &T = GetLookAheadToken(I);
if (T.is(tok::r_paren))
@@ -1085,9 +1085,13 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd) {
}
}
- if (ParseAsExpression)
+ 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()))
+ } else if (tokenIsLikeStringLiteral(Tok, getLangOpts()))
AssertMessage = ParseUnevaluatedStringLiteralExpression();
else {
Diag(Tok, diag::err_expected_string_literal)
diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp
index 08b732132228b..47e9ae9f5d2c5 100644
--- a/clang/test/Lexer/cxx-features.cpp
+++ b/clang/test/Lexer/cxx-features.cpp
@@ -321,7 +321,7 @@
#error "wrong value for __cpp_range_based_for"
#endif
-#if check(static_assert, 0, 200410, 200410, 201411, 201411, 201411, 202306)
+#if check(static_assert, 0, 202306, 202306, 202306, 202306, 202306, 202306)
#error "wrong value for __cpp_static_assert"
#endif
diff --git a/clang/test/SemaCXX/static-assert-ext.cpp b/clang/test/SemaCXX/static-assert-ext.cpp
new file mode 100644
index 0000000000000..05f7a0e96974a
--- /dev/null
+++ b/clang/test/SemaCXX/static-assert-ext.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -std=c++98 -fsyntax-only -pedantic %s -verify=precxx11,precxx17,precxx26
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -pedantic %s -verify=since-cxx11,precxx17,precxx26 -Wc++98-compat
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only -pedantic %s -verify=since-cxx11,since-cxx17,precxx26 -Wc++98-compat -Wpre-c++17-compat
+// RUN: %clang_cc1 -std=c++26 -fsyntax-only -pedantic %s -verify=since-cxx11,since-cxx17,since-cxx26 -Wc++98-compat -Wpre-c++17-compat -Wpre-c++26-compat
+
+static_assert(false, "a");
+// precxx11-error at -1 {{a type specifier is required for all declarations}}
+// since-cxx11-warning at -2 {{'static_assert' declarations are incompatible with C++98}}
+// since-cxx11-error at -3 {{static assertion failed: a}}
+
+#if __cplusplus >= 201103L
+static_assert(false);
+// since-cxx11-warning at -1 {{'static_assert' declarations are incompatible with C++98}}
+// precxx17-warning at -2 {{'static_assert' with no message is a C++17 extension}}
+// since-cxx17-warning at -3 {{'static_assert' with no message is incompatible with C++ standards before C++17}}
+// since-cxx11-error at -4 {{static assertion failed}}
+
+struct X {
+ static constexpr int size() { return 1; } // since-cxx11-warning {{'constexpr'}}
+ static constexpr const char* data() { return "b"; } // since-cxx11-warning {{'constexpr'}}
+};
+
+static_assert(false, X());
+// since-cxx11-warning at -1 {{'static_assert' declarations are incompatible with C++98}}
+// precxx26-warning at -2 {{'static_assert' with a user-generated message is a C++26 extension}}
+// since-cxx26-warning at -3 {{'static_assert' with a user-generated message is incompatible with C++ standards before C++26}}
+// since-cxx11-error at -4 {{static assertion failed: b}}
+#endif
>From 0de07a58beac51dc260caaeec405fe81d89370fc Mon Sep 17 00:00:00 2001
From: Mital Ashok <mital at mitalashok.co.uk>
Date: Tue, 6 Aug 2024 11:19:44 +0100
Subject: [PATCH 2/8] Add release note
---
clang/docs/ReleaseNotes.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0f1a4c1851911..20937673c688e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -105,6 +105,11 @@ C2y Feature Support
C23 Feature Support
^^^^^^^^^^^^^^^^^^^
+Non-comprehensive list of changes in this release
+-------------------------------------------------
+
+- Accept C++26 user-defined ``static_assert`` messages in C++11 as an extension.
+
New Compiler Flags
------------------
>From 107621339a766bd234d1971d862ad1f1c5a13bd6 Mon Sep 17 00:00:00 2001
From: Mital Ashok <mital at mitalashok.co.uk>
Date: Tue, 6 Aug 2024 11:20:11 +0100
Subject: [PATCH 3/8] Fix test failure
---
clang/test/CXX/drs/cwg27xx.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/CXX/drs/cwg27xx.cpp b/clang/test/CXX/drs/cwg27xx.cpp
index 406c8ea41f3b2..dc8b5de7054cd 100644
--- a/clang/test/CXX/drs/cwg27xx.cpp
+++ b/clang/test/CXX/drs/cwg27xx.cpp
@@ -134,7 +134,7 @@ void test() {
}
namespace cwg2798 { // cwg2798: 17
-#if __cpp_static_assert >= 202306
+#if __cplusplus > 202302L
struct string {
constexpr string() {
data_ = new char[6]();
>From 34c80e728ed08a0fedf4bee52b71a7bc44b00fe7 Mon Sep 17 00:00:00 2001
From: Mital Ashok <mital at mitalashok.co.uk>
Date: Tue, 6 Aug 2024 12:17:00 +0100
Subject: [PATCH 4/8] Do not change feature test macro
---
clang/docs/LanguageExtensions.rst | 4 ++--
clang/lib/Frontend/InitPreprocessor.cpp | 6 ++++--
clang/test/Lexer/cxx-features.cpp | 2 +-
3 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 5953ca5259da2..c6d5c387562e5 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1483,7 +1483,7 @@ Generic lambda expressions __cpp_generic_lambdas C+
variable templates __cpp_variable_templates C++14 C++03
Binary literals __cpp_binary_literals C++14 C++03
Relaxed constexpr __cpp_constexpr C++14 C++11
-Static assert with no message __cpp_static_assert>=201411L C++17 C++11
+Static assert with no message C++17 C++11
Pack expansion in generalized lambda-capture __cpp_init_captures C++17 C++03
``if constexpr`` __cpp_if_constexpr C++17 C++11
fold expressions __cpp_fold_expressions C++17 C++03
@@ -1504,7 +1504,7 @@ Conditional ``explicit`` __cpp_conditional_explicit C+
``static operator()`` __cpp_static_call_operator C++23 C++03
Attributes on Lambda-Expressions C++23 C++11
Attributes on Structured Bindings __cpp_structured_bindings C++26 C++03
-Static assert with user-generated message __cpp_static_assert>=202306L C++26 C++11
+Static assert with user-generated message C++26 C++11
Pack Indexing __cpp_pack_indexing C++26 C++03
``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03
-------------------------------------------- -------------------------------- ------------- -------------
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 038fad5272be7..8e62461d8a181 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -671,8 +671,10 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
LangOpts.CPlusPlus23 ? "202211L"
: LangOpts.CPlusPlus17 ? "201603L"
: "200907");
- // C++17 / C++26 static_assert backported
- Builder.defineMacro("__cpp_static_assert", "202306L");
+ Builder.defineMacro("__cpp_static_assert", LangOpts.CPlusPlus26 ? "202306L"
+ : LangOpts.CPlusPlus17
+ ? "201411L"
+ : "200410");
Builder.defineMacro("__cpp_decltype", "200707L");
Builder.defineMacro("__cpp_attributes", "200809L");
Builder.defineMacro("__cpp_rvalue_references", "200610L");
diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp
index 47e9ae9f5d2c5..08b732132228b 100644
--- a/clang/test/Lexer/cxx-features.cpp
+++ b/clang/test/Lexer/cxx-features.cpp
@@ -321,7 +321,7 @@
#error "wrong value for __cpp_range_based_for"
#endif
-#if check(static_assert, 0, 202306, 202306, 202306, 202306, 202306, 202306)
+#if check(static_assert, 0, 200410, 200410, 201411, 201411, 201411, 202306)
#error "wrong value for __cpp_static_assert"
#endif
>From b842c0f87bbe1410e76a0fa5e38ae3805e692caa Mon Sep 17 00:00:00 2001
From: Mital Ashok <mital at mitalashok.co.uk>
Date: Tue, 6 Aug 2024 12:39:15 +0100
Subject: [PATCH 5/8] Fix more test failures
---
clang/test/Parser/cxx11-user-defined-literals.cpp | 3 ++-
clang/test/Sema/static-assert.c | 8 ++++++--
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/clang/test/Parser/cxx11-user-defined-literals.cpp b/clang/test/Parser/cxx11-user-defined-literals.cpp
index 1a7e780588229..cdd06729efc39 100644
--- a/clang/test/Parser/cxx11-user-defined-literals.cpp
+++ b/clang/test/Parser/cxx11-user-defined-literals.cpp
@@ -21,7 +21,8 @@ int f() {
asm("mov %eax, %rdx"_foo); // expected-error {{user-defined suffix cannot be used here}}
}
-static_assert(true, "foo"_bar); // expected-error {{user-defined suffix cannot be used here}}
+static_assert(true, "foo"_bar); // expected-error {{no matching literal operator for call to 'operator""_bar'}}
+// expected-warning at -1 {{'static_assert' with a user-generated message is a C++26 extension}}
int cake() __attribute__((availability(macosx, unavailable, message = "is a lie"_x))); // expected-error {{user-defined suffix cannot be used here}}
diff --git a/clang/test/Sema/static-assert.c b/clang/test/Sema/static-assert.c
index 4e9e6b7ee558b..d603bc19bb824 100644
--- a/clang/test/Sema/static-assert.c
+++ b/clang/test/Sema/static-assert.c
@@ -25,8 +25,12 @@ void foo(void) {
#endif
}
-_Static_assert(1, invalid); // expected-error {{expected string literal for diagnostic message in static_assert}} \
- // ext-warning {{'_Static_assert' is a C11 extension}}
+_Static_assert(1, invalid); // ext-warning {{'_Static_assert' is a C11 extension}}
+#ifndef __cplusplus
+// expected-error at -2 {{expected string literal for diagnostic message in static_assert}}
+#endif
+// cxx-error at -4 {{use of undeclared identifier 'invalid'}}
+// cxx-warning at -5 {{'static_assert' with a user-generated message is a C++26 extension}}
struct A {
int a;
>From 49184dc71552eac3d91d45be74142e18ac4a64a1 Mon Sep 17 00:00:00 2001
From: Mital Ashok <mital at mitalashok.co.uk>
Date: Tue, 6 Aug 2024 17:42:51 +0100
Subject: [PATCH 6/8] Do not "Do not change feature test macro"
---
clang/docs/LanguageExtensions.rst | 4 ++--
clang/lib/Frontend/InitPreprocessor.cpp | 7 +++----
clang/test/Lexer/cxx-features.cpp | 2 +-
3 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index c6d5c387562e5..315143b336946 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1483,7 +1483,7 @@ Generic lambda expressions __cpp_generic_lambdas C+
variable templates __cpp_variable_templates C++14 C++03
Binary literals __cpp_binary_literals C++14 C++03
Relaxed constexpr __cpp_constexpr C++14 C++11
-Static assert with no message C++17 C++11
+Static assert with no message __cpp_static_assert>=201411L C++17 C++11
Pack expansion in generalized lambda-capture __cpp_init_captures C++17 C++03
``if constexpr`` __cpp_if_constexpr C++17 C++11
fold expressions __cpp_fold_expressions C++17 C++03
@@ -1504,7 +1504,7 @@ Conditional ``explicit`` __cpp_conditional_explicit C+
``static operator()`` __cpp_static_call_operator C++23 C++03
Attributes on Lambda-Expressions C++23 C++11
Attributes on Structured Bindings __cpp_structured_bindings C++26 C++03
-Static assert with user-generated message C++26 C++11
+Static assert with user-generated message __cpp_static_assert>=201411L C++26 C++11
Pack Indexing __cpp_pack_indexing C++26 C++03
``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03
-------------------------------------------- -------------------------------- ------------- -------------
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 8e62461d8a181..6c1933691c077 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -671,10 +671,9 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
LangOpts.CPlusPlus23 ? "202211L"
: LangOpts.CPlusPlus17 ? "201603L"
: "200907");
- Builder.defineMacro("__cpp_static_assert", LangOpts.CPlusPlus26 ? "202306L"
- : LangOpts.CPlusPlus17
- ? "201411L"
- : "200410");
+ // C++17 / C++26 static_assert supported as an extension in earlier language
+ // modes, so we use the C++26 value.
+ Builder.defineMacro("__cpp_static_assert", "202306L");
Builder.defineMacro("__cpp_decltype", "200707L");
Builder.defineMacro("__cpp_attributes", "200809L");
Builder.defineMacro("__cpp_rvalue_references", "200610L");
diff --git a/clang/test/Lexer/cxx-features.cpp b/clang/test/Lexer/cxx-features.cpp
index 08b732132228b..47e9ae9f5d2c5 100644
--- a/clang/test/Lexer/cxx-features.cpp
+++ b/clang/test/Lexer/cxx-features.cpp
@@ -321,7 +321,7 @@
#error "wrong value for __cpp_range_based_for"
#endif
-#if check(static_assert, 0, 200410, 200410, 201411, 201411, 201411, 202306)
+#if check(static_assert, 0, 202306, 202306, 202306, 202306, 202306, 202306)
#error "wrong value for __cpp_static_assert"
#endif
>From 0d5d8db4fee3007849e869ed7a7eaf1888abd774 Mon Sep 17 00:00:00 2001
From: Mital Ashok <mital at mitalashok.co.uk>
Date: Tue, 6 Aug 2024 17:55:30 +0100
Subject: [PATCH 7/8] Copy-paste error
---
clang/docs/LanguageExtensions.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 315143b336946..5953ca5259da2 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1504,7 +1504,7 @@ Conditional ``explicit`` __cpp_conditional_explicit C+
``static operator()`` __cpp_static_call_operator C++23 C++03
Attributes on Lambda-Expressions C++23 C++11
Attributes on Structured Bindings __cpp_structured_bindings C++26 C++03
-Static assert with user-generated message __cpp_static_assert>=201411L C++26 C++11
+Static assert with user-generated message __cpp_static_assert>=202306L C++26 C++11
Pack Indexing __cpp_pack_indexing C++26 C++03
``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03
-------------------------------------------- -------------------------------- ------------- -------------
>From f0ee16a6895e66435044e644127cdc785c21469c Mon Sep 17 00:00:00 2001
From: Mital Ashok <mital at mitalashok.co.uk>
Date: Tue, 6 Aug 2024 18:07:41 +0100
Subject: [PATCH 8/8] This spacing is nicer. Might fix documentation build
failure?
---
clang/docs/LanguageExtensions.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst
index 5953ca5259da2..5f1083e8e15f6 100644
--- a/clang/docs/LanguageExtensions.rst
+++ b/clang/docs/LanguageExtensions.rst
@@ -1483,7 +1483,7 @@ Generic lambda expressions __cpp_generic_lambdas C+
variable templates __cpp_variable_templates C++14 C++03
Binary literals __cpp_binary_literals C++14 C++03
Relaxed constexpr __cpp_constexpr C++14 C++11
-Static assert with no message __cpp_static_assert>=201411L C++17 C++11
+Static assert with no message __cpp_static_assert >= 201411L C++17 C++11
Pack expansion in generalized lambda-capture __cpp_init_captures C++17 C++03
``if constexpr`` __cpp_if_constexpr C++17 C++11
fold expressions __cpp_fold_expressions C++17 C++03
@@ -1504,7 +1504,7 @@ Conditional ``explicit`` __cpp_conditional_explicit C+
``static operator()`` __cpp_static_call_operator C++23 C++03
Attributes on Lambda-Expressions C++23 C++11
Attributes on Structured Bindings __cpp_structured_bindings C++26 C++03
-Static assert with user-generated message __cpp_static_assert>=202306L C++26 C++11
+Static assert with user-generated message __cpp_static_assert >= 202306L C++26 C++11
Pack Indexing __cpp_pack_indexing C++26 C++03
``= delete ("should have a reason");`` __cpp_deleted_function C++26 C++03
-------------------------------------------- -------------------------------- ------------- -------------
More information about the cfe-commits
mailing list