[openmp] [lldb] [llvm] [libcxx] [libc] [clang-tools-extra] [compiler-rt] [lld] [flang] [libcxxabi] [clang] [mlir] [libunwind] [C23] Implement N3018: The constexpr specifier for object definitions (PR #73099)

Guillot Tony via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 11 07:27:27 PST 2023


================
@@ -0,0 +1,287 @@
+// 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;
----------------
to268 wrote:

I would preferably suggest to add a couple of `constexpr auto` tests, theses cases bellow should be enough to make sure that no divergence has been introduced.
```c
constexpr auto Ulong = 1L;
constexpr auto CompoundLiterral = (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}}
```

Adding some `_Static_assert` would be better to also make sure that the `auto` keyword is on par when adding the `constexpr` keyword.
```c
_Static_assert(_Generic(Ulong, long : 1));
_Static_assert(_Generic(CompoundLiterral, int : 1));
_Static_assert(_Generic(DoubleCast, double : 1));
_Static_assert(_Generic(String, char* : 1));
```

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


More information about the cfe-commits mailing list