]> granicus.if.org Git - clang/commitdiff
For P0784R7: add further testing of requirements on constexpr
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 23 Sep 2019 05:08:55 +0000 (05:08 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 23 Sep 2019 05:08:55 +0000 (05:08 +0000)
destructors.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@372541 91177308-0d34-0410-b5e6-96231b3b80d8

test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp [new file with mode: 0644]

diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp
new file mode 100644 (file)
index 0000000..3d45949
--- /dev/null
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -std=c++2a -verify %s
+
+// p3: if the function is a constructor or destructor, its class shall not have
+// any virtual base classes;
+namespace vbase {
+  struct A {};
+  struct B : virtual A { // expected-note {{virtual}}
+    constexpr ~B() {} // expected-error {{constexpr member function not allowed in struct with virtual base class}}
+  };
+}
+
+// p3: its function-body shall not enclose
+//  -- a goto statement
+//  -- an identifier label
+//  -- a variable of non-literal type or of static or thread storage duration
+namespace contents {
+  struct A {
+    constexpr ~A() {
+      goto x; // expected-error {{statement not allowed in constexpr function}}
+      x: ;
+    }
+  };
+  struct B {
+    constexpr ~B() {
+      x: ; // expected-error {{statement not allowed in constexpr function}}
+    }
+  };
+  struct Nonlit { Nonlit(); }; // expected-note {{not literal}}
+  struct C {
+    constexpr ~C() {
+      Nonlit nl; // expected-error {{non-literal}}
+    }
+  };
+  struct D {
+    constexpr ~D() {
+      static int a; // expected-error {{static variable}}
+    }
+  };
+  struct E {
+    constexpr ~E() {
+      thread_local int e; // expected-error {{thread_local variable}}
+    }
+  };
+  struct F {
+    constexpr ~F() {
+      extern int f;
+    }
+  };
+}
+
+// p5: for every subobject of class type or (possibly multi-dimensional) array
+// thereof, that class type shall have a constexpr destructor
+namespace subobject {
+  struct A {
+    ~A();
+  };
+  struct B : A { // expected-note {{here}}
+    constexpr ~B() {} // expected-error {{destructor cannot be declared constexpr because base class 'subobject::A' does not have a constexpr destructor}}
+  };
+  struct C {
+    A a; // expected-note {{here}}
+    constexpr ~C() {} // expected-error {{destructor cannot be declared constexpr because data member 'a' does not have a constexpr destructor}}
+  };
+  struct D : A {
+    A a;
+    constexpr ~D() = delete;
+  };
+}