From dca01801bb84b4ad173b7cb71d6de46a9390a58d Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 23 Sep 2019 05:08:55 +0000 Subject: [PATCH] For P0784R7: add further testing of requirements on constexpr destructors. llvm-svn: 372541 --- .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp | 68 ++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp new file mode 100644 index 0000000..3d45949 --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/dtor.cpp @@ -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; + }; +} -- 2.7.4