[clang] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)

Mariya Podchishchaeva via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 26 09:11:22 PST 2024


================
@@ -0,0 +1,296 @@
+// RUN: %clang_cc1 -std=c2x -verify -triple x86_64 -pedantic -Wno-conversion -Wno-constant-conversion -Wno-div-by-zero %s
+
+// Check that constexpr only applies to variables.
+constexpr void f0() {} // expected-error {{'constexpr' can only be used in variable declarations}}
+constexpr const int f1() { return 0; } // expected-error {{'constexpr' can only be used in variable declarations}}
+
+constexpr struct S1 { int f; }; //expected-error {{struct cannot be marked constexpr}}
+constexpr struct S2 ; // expected-error {{struct cannot be marked constexpr}}
+constexpr union U1; // expected-error {{union cannot be marked constexpr}}
+constexpr union U2 {int a; float b;}; // expected-error {{union cannot be marked constexpr}}
+constexpr enum E1 {A = 1, B = 2} ; // expected-error {{enum cannot be marked constexpr}}
+struct S3 {
+  static constexpr int f = 0; // expected-error {{type name does not allow storage class}}
+  // expected-error at -1 {{type name does not allow constexpr}}
+  // expected-error at -2 {{expected ';' at end}}
+  constexpr int f1 = 0;
+  // expected-error at -1 {{type name does not allow constexpr}}
+  // expected-error at -2 {{expected ';' at end}}
+};
+
+constexpr; // expected-error {{'constexpr' can only be used in variable declarations}}
+constexpr int V1 = 3;
+constexpr float V2 = 7.0;
+int V3 = (constexpr)3; // expected-error {{expected expression}}
+
+void f2() {
+  constexpr int a = 0;
+  constexpr float b = 1.7f;
+}
+
+// Check how constexpr works with other storage-class specifiers.
+constexpr auto V4 = 1;
+constexpr static auto V5 = 1;
+constexpr static const auto V6 = 1;
+constexpr static const int V7 = 1;
+constexpr static int V8 = 1;
+constexpr auto Ulong = 1L;
+constexpr auto CompoundLiteral = (int){13};
+constexpr auto DoubleCast = (double)(1 / 3);
+constexpr auto String = "this is a string";
+constexpr signed auto Long = 1L; // expected-error {{'auto' cannot be signed or unsigned}}
+_Static_assert(_Generic(Ulong, long : 1));
+_Static_assert(_Generic(CompoundLiteral, int : 1));
+_Static_assert(_Generic(DoubleCast, double : 1));
+_Static_assert(_Generic(String, char* : 1));
+
+void f3(constexpr register int P1) { // expected-error {{function parameter cannot be constexpr}}
+  constexpr register int V9 = 0;
+  constexpr register auto V10 = 0.0;
+}
+
+constexpr thread_local int V11 = 38; // expected-error {{cannot combine with previous '_Thread_local' declaration specifier}}
+constexpr static thread_local double V12 = 38; // expected-error {{cannot combine with previous '_Thread_local' declaration specifier}}
+constexpr extern thread_local char V13; // expected-error {{cannot combine with previous '_Thread_local' declaration specifier}}
+// expected-error at -1 {{cannot combine with previous 'extern' declaration specifier}}
+// expected-error at -2 {{constexpr variable declaration must be a definition}}
+constexpr thread_local short V14 = 38; // expected-error {{cannot combine with previous '_Thread_local' declaration specifier}}
+
+// Check how constexpr works with qualifiers.
+constexpr _Atomic int V15 = 0; // expected-error {{constexpr variable cannot have type 'const _Atomic(int)'}}
+constexpr _Atomic(int) V16 = 0; // expected-error {{constexpr variable cannot have type 'const _Atomic(int)'}}
+
+constexpr volatile int V17 = 0; // expected-error {{constexpr variable cannot have type 'const volatile int'}}
+
+constexpr int * restrict V18 = 0; // expected-error {{constexpr variable cannot have type 'int *const restrict'}}
----------------
Fznamznon wrote:

Added, line 71.

https://github.com/llvm/llvm-project/pull/73099


More information about the cfe-commits mailing list