summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-12-22 02:22:31 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-12-22 02:22:31 +0000
commitcc36f698afe0132a3c7f5417d4469aee2f8cbaf2 (patch)
tree206d9c5495d01c1a49678847a07ab27d34c44680 /clang/test
parent1c3b1efa58a0365a4e0a2a77c4e1baf1b4ce7466 (diff)
downloadbcm5719-llvm-cc36f698afe0132a3c7f5417d4469aee2f8cbaf2.tar.gz
bcm5719-llvm-cc36f698afe0132a3c7f5417d4469aee2f8cbaf2.zip
PR11614: Mark defaulted special constructors as constexpr if their implicit
definition would satisfy the constexpr requirements. llvm-svn: 147128
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp9
-rw-r--r--clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp2
-rw-r--r--clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp55
-rw-r--r--clang/test/CXX/special/class.copy/p13-0x.cpp55
-rw-r--r--clang/test/CXX/special/class.ctor/p6-0x.cpp49
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp9
-rw-r--r--clang/test/SemaCXX/enum-bitfield.cpp4
7 files changed, 170 insertions, 13 deletions
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
index 809a0cb1763..f173748e967 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp
@@ -42,13 +42,12 @@ class C2 {} constexpr; // expected-error {{class cannot be marked constexpr}}
struct S2 {} constexpr; // expected-error {{struct cannot be marked constexpr}}
union U2 {} constexpr; // expected-error {{union cannot be marked constexpr}}
enum E2 {} constexpr; // expected-error {{enum cannot be marked constexpr}}
-// FIXME: Mark default constructors as 'constexpr' when appropriate.
-constexpr class C3 {} c3 = C3(); // unexpected-error {{must be initialized by a constant expression}} unexpected-note {{non-constexpr constructor}} unexpected-note {{here}}
-constexpr struct S3 {} s3 = S3(); // unexpected-error {{must be initialized by a constant expression}} unexpected-note {{non-constexpr constructor}} unexpected-note {{here}}
+constexpr class C3 {} c3 = C3();
+constexpr struct S3 {} s3 = S3();
constexpr union U3 {} u3 = {};
constexpr enum E3 { V3 } e3 = V3;
-class C4 {} constexpr c4 = C4(); // unexpected-error {{must be initialized by a constant expression}} unexpected-note {{non-constexpr constructor}} unexpected-note {{here}}
-struct S4 {} constexpr s4 = S4(); // unexpected-error {{must be initialized by a constant expression}} unexpected-note {{non-constexpr constructor}} unexpected-note {{here}}
+class C4 {} constexpr c4 = C4();
+struct S4 {} constexpr s4 = S4();
union U4 {} constexpr u4 = {};
enum E4 { V4 } constexpr e4 = V4;
constexpr int; // expected-error {{constexpr can only be used in variable and function declarations}}
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
index 03406dbf918..1b31d21f36d 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -30,7 +30,7 @@ struct SS : S {
// The definition of a constexpr function shall satisfy the following
// constraints:
-struct T : SS { // expected-note {{base class 'SS' of non-literal type}}
+struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}}
constexpr T(); // expected-error {{non-literal type 'T' cannot have constexpr members}}
// - it shall not be virtual;
diff --git a/clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp b/clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
new file mode 100644
index 00000000000..d401a97ca25
--- /dev/null
+++ b/clang/test/CXX/dcl.decl/dcl.fct.def/dcl.fct.def.default/p2.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// An explicitly-defaulted function may be declared constexpr only if it would
+// have been implicitly declared as constexpr.
+struct S1 {
+ constexpr S1() = default; // expected-error {{defaulted definition of default constructor is not constexpr}}
+ constexpr S1(const S1&) = default;
+ constexpr S1(S1&&) = default;
+ constexpr S1 &operator=(const S1&) = default; // expected-error {{explicitly-defaulted copy assignment operator may not have}}
+ constexpr S1 &operator=(S1&&) = default; // expected-error {{explicitly-defaulted move assignment operator may not have}}
+ constexpr ~S1() = default; // expected-error {{destructor cannot be marked constexpr}}
+ int n;
+};
+struct NoCopyMove {
+ constexpr NoCopyMove() {}
+ NoCopyMove(const NoCopyMove&);
+ NoCopyMove(NoCopyMove&&);
+};
+struct S2 {
+ constexpr S2() = default;
+ constexpr S2(const S2&) = default; // expected-error {{defaulted definition of copy constructor is not constexpr}}
+ constexpr S2(S2&&) = default; // expected-error {{defaulted definition of move constructor is not constexpr}}
+ NoCopyMove ncm;
+};
+
+// If a function is explicitly defaulted on its first declaration
+// -- it is implicitly considered to be constexpr if the implicit declaration
+// would be
+struct S3 {
+ S3() = default; // expected-note {{here}}
+ S3(const S3&) = default;
+ S3(S3&&) = default;
+ constexpr S3(int n) : n(n) {}
+ int n;
+};
+constexpr S3 s3a = S3(0);
+constexpr S3 s3b = s3a;
+constexpr S3 s3c = S3(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
+
+struct S4 {
+ S4() = default;
+ S4(const S4&) = default; // expected-note {{here}}
+ S4(S4&&) = default; // expected-note {{here}}
+ NoCopyMove ncm;
+};
+constexpr S4 s4a; // ok
+constexpr S4 s4b = S4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
+constexpr S4 s4c = s4a; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
+
+struct S5 {
+ constexpr S5();
+ int n = 1, m = n + 3;
+};
+constexpr S5::S5() = default;
+static_assert(S5().m == 4, "");
diff --git a/clang/test/CXX/special/class.copy/p13-0x.cpp b/clang/test/CXX/special/class.copy/p13-0x.cpp
new file mode 100644
index 00000000000..30d8c6ebad8
--- /dev/null
+++ b/clang/test/CXX/special/class.copy/p13-0x.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// If the implicitly-defined constructor would satisfy the requirements of a
+// constexpr constructor, the implicitly-defined constructor is constexpr.
+struct Constexpr1 {
+ constexpr Constexpr1() : n(0) {}
+ int n;
+};
+constexpr Constexpr1 c1a = Constexpr1(Constexpr1()); // ok
+constexpr Constexpr1 c1b = Constexpr1(Constexpr1(c1a)); // ok
+
+struct Constexpr2 {
+ Constexpr1 ce1;
+ constexpr Constexpr2() = default;
+ constexpr Constexpr2(const Constexpr2 &o) : ce1(o.ce1) {}
+ // no move constructor
+};
+
+constexpr Constexpr2 c2a = Constexpr2(Constexpr2()); // ok
+constexpr Constexpr2 c2b = Constexpr2(Constexpr2(c2a)); // ok
+
+struct Constexpr3 {
+ Constexpr2 ce2;
+ // all special constructors are constexpr, move ctor calls ce2's copy ctor
+};
+
+constexpr Constexpr3 c3a = Constexpr3(Constexpr3()); // ok
+constexpr Constexpr3 c3b = Constexpr3(Constexpr3(c3a)); // ok
+
+struct NonConstexprCopy {
+ constexpr NonConstexprCopy() = default;
+ NonConstexprCopy(const NonConstexprCopy &);
+ constexpr NonConstexprCopy(NonConstexprCopy &&) = default;
+
+ int n = 42;
+};
+
+NonConstexprCopy::NonConstexprCopy(const NonConstexprCopy &) = default; // expected-note {{here}}
+
+constexpr NonConstexprCopy ncc1 = NonConstexprCopy(NonConstexprCopy()); // ok
+constexpr NonConstexprCopy ncc2 = ncc1; // expected-error {{constant expression}} expected-note {{non-constexpr constructor}}
+
+struct NonConstexprDefault {
+ NonConstexprDefault() = default;
+ constexpr NonConstexprDefault(int n) : n(n) {}
+ int n;
+};
+struct Constexpr4 {
+ NonConstexprDefault ncd;
+};
+
+constexpr NonConstexprDefault ncd = NonConstexprDefault(NonConstexprDefault(1));
+constexpr Constexpr4 c4a = { ncd };
+constexpr Constexpr4 c4b = Constexpr4(c4a);
+constexpr Constexpr4 c4c = Constexpr4(static_cast<Constexpr4&&>(const_cast<Constexpr4&>(c4b)));
diff --git a/clang/test/CXX/special/class.ctor/p6-0x.cpp b/clang/test/CXX/special/class.ctor/p6-0x.cpp
new file mode 100644
index 00000000000..19e324d8df6
--- /dev/null
+++ b/clang/test/CXX/special/class.ctor/p6-0x.cpp
@@ -0,0 +1,49 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+// Implicitly-defined default constructors are constexpr if the implicit
+// definition would be.
+struct NonConstexpr1 { // expected-note {{here}}
+ int a;
+};
+struct NonConstexpr2 { // expected-note {{here}}
+ NonConstexpr1 nl;
+};
+constexpr NonConstexpr1 nc1 = NonConstexpr1(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr1'}}
+constexpr NonConstexpr2 nc2 = NonConstexpr2(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr2'}}
+
+struct Constexpr1 {};
+constexpr Constexpr1 c1 = Constexpr1(); // ok
+struct NonConstexpr3 : virtual Constexpr1 {};
+constexpr NonConstexpr3 nc3 = NonConstexpr3(); // expected-error {{constant expression}} expected-note {{non-literal type 'const NonConstexpr3'}}
+
+struct Constexpr2 {
+ int a = 0;
+};
+constexpr Constexpr2 c2 = Constexpr2(); // ok
+
+int n;
+struct Member {
+ Member() : a(n) {}
+ constexpr Member(int&a) : a(a) {}
+ int &a;
+};
+struct NonConstexpr4 { // expected-note {{here}}
+ Member m;
+};
+constexpr NonConstexpr4 nc4 = NonConstexpr4(); // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr4'}}
+struct Constexpr3 {
+ constexpr Constexpr3() : m(n) {}
+ Member m;
+};
+constexpr Constexpr3 c3 = Constexpr3(); // ok
+struct Constexpr4 {
+ Constexpr3 m;
+};
+constexpr Constexpr4 c4 = Constexpr4(); // ok
+
+
+// This rule breaks some legal C++98 programs!
+struct A {}; // expected-note {{here}}
+struct B {
+ friend A::A(); // expected-error {{non-constexpr declaration of 'A' follows constexpr declaration}}
+};
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 995cd2ffece..0993a982d8e 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -86,7 +86,7 @@ namespace TemplateArgumentConversion {
using IntParam0 = IntParam<0>;
using IntParam0 = IntParam<id(0)>;
- using IntParam0 = IntParam<MemberZero().zero>; // expected-error {{did you mean to call it with no arguments?}} expected-error {{not an integral constant expression}}
+ using IntParam0 = IntParam<MemberZero().zero>; // expected-error {{did you mean to call it with no arguments?}}
}
namespace CaseStatements {
@@ -517,16 +517,15 @@ struct D {
};
static_assert(D().c.n == 42, "");
-struct E { // expected-note {{here}}
+struct E {
constexpr E() : p(&p) {} // expected-note {{pointer to temporary cannot be used to initialize a member in a constant expression}}
void *p;
};
constexpr const E &e1 = E(); // expected-error {{constant expression}} expected-note {{in call to 'E()'}} expected-note {{temporary created here}}
// This is a constant expression if we elide the copy constructor call, and
// is not a constant expression if we don't! But we do, so it is.
-// FIXME: The move constructor is not currently implicitly defined as constexpr.
-constexpr E e2 = E(); // unexpected-error {{constant expression}} unexpected-note {{here}} unexpected-note {{non-constexpr constructor 'E' cannot be used in a constant expression}}
-static_assert(e2.p == &e2.p, ""); // unexpected-error {{constant expression}} unexpected-note {{initializer of 'e2' is not a constant expression}}
+constexpr E e2 = E();
+static_assert(e2.p == &e2.p, "");
constexpr E e3;
static_assert(e3.p == &e3.p, "");
diff --git a/clang/test/SemaCXX/enum-bitfield.cpp b/clang/test/SemaCXX/enum-bitfield.cpp
index 8cfc21f9655..1a657408f8a 100644
--- a/clang/test/SemaCXX/enum-bitfield.cpp
+++ b/clang/test/SemaCXX/enum-bitfield.cpp
@@ -2,7 +2,7 @@
enum E {};
-struct Z {}; // expected-note {{here}}
+struct Z {};
typedef int Integer;
struct X {
@@ -14,5 +14,5 @@ struct X {
struct Y {
enum E : int(2);
- enum E : Z(); // expected-error{{not an integer constant}} expected-note {{non-constexpr constructor 'Z'}}
+ enum E : Z(); // expected-error{{not an integer constant}}
};
OpenPOWER on IntegriCloud