aboutsummaryrefslogtreecommitdiff
path: root/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2013-06-10 20:45:12 +0000
committerDimitry Andric <dim@FreeBSD.org>2013-06-10 20:45:12 +0000
commit6a0372513edbc473b538d2f724efac50405d6fef (patch)
tree8f7776b7310bebaf415ac5b69e46e9f928c37144 /test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
parent809500fc2c13c8173a16b052304d983864e4a1e1 (diff)
downloadsrc-6a0372513edbc473b538d2f724efac50405d6fef.tar.gz
src-6a0372513edbc473b538d2f724efac50405d6fef.zip
Vendor import of clang tags/RELEASE_33/final r183502 (effectively, 3.3vendor/clang/clang-release_33-r183502
Notes
Notes: svn path=/vendor/clang/dist/; revision=251609 svn path=/vendor/clang/clang-release_33-r183502/; revision=251610; tag=vendor/clang/clang-release_33-r183502
Diffstat (limited to 'test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp')
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp202
1 files changed, 176 insertions, 26 deletions
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
index cafdd635518c..4393727c193b 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p3.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -verify -std=c++11 %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++11 -Werror=c++1y-extensions %s
+// RUN: %clang_cc1 -verify -fcxx-exceptions -triple=x86_64-linux-gnu -std=c++1y -DCXX1Y %s
namespace N {
typedef char C;
@@ -8,7 +9,7 @@ namespace M {
typedef double D;
}
-struct NonLiteral { // expected-note 2{{no constexpr constructors}}
+struct NonLiteral { // expected-note 3{{no constexpr constructors}}
NonLiteral() {}
NonLiteral(int) {}
};
@@ -28,45 +29,53 @@ struct SS : S {
// constraints:
struct T : SS, NonLiteral { // expected-note {{base class 'NonLiteral' of non-literal type}}
constexpr T();
- constexpr int f(); // expected-error {{non-literal type 'T' cannot have constexpr members}}
+ constexpr int f() const; // expected-error {{non-literal type 'T' cannot have constexpr members}}
// - it shall not be virtual;
- virtual constexpr int ExplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}}
+ virtual constexpr int ExplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
- constexpr int ImplicitlyVirtual() { return 0; } // expected-error {{virtual function cannot be constexpr}}
+ constexpr int ImplicitlyVirtual() const { return 0; } // expected-error {{virtual function cannot be constexpr}}
// - its return type shall be a literal type;
- constexpr NonLiteral NonLiteralReturn() { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
- constexpr void VoidReturn() { return; } // expected-error {{constexpr function's return type 'void' is not a literal type}}
+ constexpr NonLiteral NonLiteralReturn() const { return {}; } // expected-error {{constexpr function's return type 'NonLiteral' is not a literal type}}
+ constexpr void VoidReturn() const { return; }
+#ifndef CXX1Y
+ // expected-error@-2 {{constexpr function's return type 'void' is not a literal type}}
+#endif
constexpr ~T(); // expected-error {{destructor cannot be marked constexpr}}
- typedef NonLiteral F();
+ typedef NonLiteral F() const;
constexpr F NonLiteralReturn2; // ok until definition
// - each of its parameter types shall be a literal type;
- constexpr int NonLiteralParam(NonLiteral) { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
- typedef int G(NonLiteral);
+ constexpr int NonLiteralParam(NonLiteral) const { return 0; } // expected-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}}
+ typedef int G(NonLiteral) const;
constexpr G NonLiteralParam2; // ok until definition
// - its function-body shall be = delete, = default,
- constexpr int Deleted() = delete;
- // It's not possible for the function-body to legally be "= default" here.
+ constexpr int Deleted() const = delete;
+ // It's not possible for the function-body to legally be "= default" here
+ // (that is, for a non-constructor function) in C++11.
// Other than constructors, only the copy- and move-assignment operators and
// destructor can be defaulted. Destructors can't be constexpr since they
// don't have a literal return type. Defaulted assignment operators can't be
// constexpr since they can't be const.
- constexpr T &operator=(const T&) = default; // expected-error {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
+ constexpr T &operator=(const T&) = default;
+#ifndef CXX1Y
+ // expected-error@-2 {{an explicitly-defaulted copy assignment operator may not have 'const', 'constexpr' or 'volatile' qualifiers}}
+ // expected-warning@-3 {{C++1y}}
+#endif
};
struct U {
- constexpr U SelfReturn();
- constexpr int SelfParam(U);
+ constexpr U SelfReturn() const;
+ constexpr int SelfParam(U) const;
};
struct V : virtual U { // expected-note {{here}}
- constexpr int F() { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
+ constexpr int F() const { return 0; } // expected-error {{constexpr member function not allowed in struct with virtual base class}}
};
-// or a compound-statememt that contains only
-constexpr int AllowedStmts() {
+// or a compound-statememt that contains only [CXX11]
+constexpr int AllowedStmtsCXX11() {
// - null statements
;
@@ -91,34 +100,118 @@ constexpr int AllowedStmts() {
// - and exactly one return statement
return sizeof(K) + sizeof(C) + sizeof(K);
}
+
+// or a compound-statement that does not contain [CXX1Y]
+constexpr int DisallowedStmtsCXX1Y_1() {
+ // - an asm-definition
+ asm("int3"); // expected-error {{statement not allowed in constexpr function}}
+ return 0;
+}
+constexpr int DisallowedStmtsCXX1Y_2() {
+ // - a goto statement
+ goto x; // expected-error {{statement not allowed in constexpr function}}
+x:
+ return 0;
+}
+constexpr int DisallowedStmtsCXX1Y_3() {
+ // - a try-block,
+ try {} catch (...) {} // expected-error {{statement not allowed in constexpr function}}
+ return 0;
+}
+constexpr int DisallowedStmtsCXX1Y_4() {
+ // - a definition of a variable of non-literal type
+ NonLiteral nl; // expected-error {{variable of non-literal type 'NonLiteral' cannot be defined in a constexpr function}}
+ return 0;
+}
+constexpr int DisallowedStmtsCXX1Y_5() {
+ // - a definition of a variable of static storage duration
+ static constexpr int n = 123; // expected-error {{static variable not permitted in a constexpr function}}
+ return n;
+}
+constexpr int DisallowedStmtsCXX1Y_6() {
+ // - a definition of a variable of thread storage duration
+ thread_local constexpr int n = 123; // expected-error {{thread_local variable not permitted in a constexpr function}}
+ return n;
+}
+constexpr int DisallowedStmtsCXX1Y_7() {
+ // - a definition of a variable for which no initialization is performed
+ int n; // expected-error {{variables defined in a constexpr function must be initialized}}
+ return 0;
+}
+
constexpr int ForStmt() {
- for (int n = 0; n < 10; ++n) // expected-error {{statement not allowed in constexpr function}}
+ for (int n = 0; n < 10; ++n)
+#ifndef CXX1Y
+ // expected-error@-2 {{statement not allowed in constexpr function}}
+#endif
return 0;
}
constexpr int VarDecl() {
- constexpr int a = 0; // expected-error {{variables cannot be declared in a constexpr function}}
+ int a = 0;
+#ifndef CXX1Y
+ // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}}
+#endif
+ return 0;
+}
+constexpr int ConstexprVarDecl() {
+ constexpr int a = 0;
+#ifndef CXX1Y
+ // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}}
+#endif
return 0;
}
+constexpr int VarWithCtorDecl() {
+ Literal a;
+#ifndef CXX1Y
+ // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}}
+#endif
+ return 0;
+}
+NonLiteral nl;
+constexpr NonLiteral &ExternNonLiteralVarDecl() {
+ extern NonLiteral nl;
+#ifndef CXX1Y
+ // expected-error@-2 {{variable declaration in a constexpr function is a C++1y extension}}
+#endif
+ return nl;
+}
+static_assert(&ExternNonLiteralVarDecl() == &nl, "");
constexpr int FuncDecl() {
- constexpr int ForwardDecl(int); // expected-error {{statement not allowed in constexpr function}}
+ constexpr int ForwardDecl(int);
+#ifndef CXX1Y
+ // expected-error@-2 {{use of this statement in a constexpr function is a C++1y extension}}
+#endif
return ForwardDecl(42);
}
constexpr int ClassDecl1() {
- typedef struct { } S1; // expected-error {{types cannot be defined in a constexpr function}}
+ typedef struct { } S1;
+#ifndef CXX1Y
+ // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}}
+#endif
return 0;
}
constexpr int ClassDecl2() {
- using S2 = struct { }; // expected-error {{types cannot be defined in a constexpr function}}
+ using S2 = struct { };
+#ifndef CXX1Y
+ // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}}
+#endif
return 0;
}
constexpr int ClassDecl3() {
- struct S3 { }; // expected-error {{types cannot be defined in a constexpr function}}
+ struct S3 { };
+#ifndef CXX1Y
+ // expected-error@-2 {{type definition in a constexpr function is a C++1y extension}}
+#endif
return 0;
}
constexpr int NoReturn() {} // expected-error {{no return statement in constexpr function}}
constexpr int MultiReturn() {
- return 0; // expected-note {{return statement}}
- return 0; // expected-error {{multiple return statements in constexpr function}}
+ return 0;
+ return 0;
+#ifndef CXX1Y
+ // expected-error@-2 {{multiple return statements in constexpr function}}
+ // expected-note@-4 {{return statement}}
+#endif
}
// - every constructor call and implicit conversion used in initializing the
@@ -137,3 +230,60 @@ namespace DR1364 {
return kGlobal; // expected-note {{read of non-const}}
}
}
+
+namespace rdar13584715 {
+ typedef __PTRDIFF_TYPE__ ptrdiff_t;
+
+ template<typename T> struct X {
+ static T value() {};
+ };
+
+ void foo(ptrdiff_t id) {
+ switch (id) {
+ case reinterpret_cast<ptrdiff_t>(&X<long>::value): // expected-error{{case value is not a constant expression}} \
+ // expected-note{{reinterpret_cast is not allowed in a constant expression}}
+ break;
+ }
+ }
+}
+
+namespace std_example {
+ constexpr int square(int x) {
+ return x * x;
+ }
+ constexpr long long_max() {
+ return 2147483647;
+ }
+ constexpr int abs(int x) {
+ if (x < 0)
+#ifndef CXX1Y
+ // expected-error@-2 {{C++1y}}
+#endif
+ x = -x;
+ return x;
+ }
+ constexpr int first(int n) {
+ static int value = n; // expected-error {{static variable not permitted}}
+ return value;
+ }
+ constexpr int uninit() {
+ int a; // expected-error {{must be initialized}}
+ return a;
+ }
+ constexpr int prev(int x) {
+ return --x;
+ }
+#ifndef CXX1Y
+ // expected-error@-4 {{never produces a constant expression}}
+ // expected-note@-4 {{subexpression}}
+#endif
+ constexpr int g(int x, int n) {
+ int r = 1;
+ while (--n > 0) r *= x;
+ return r;
+ }
+#ifndef CXX1Y
+ // expected-error@-5 {{C++1y}}
+ // expected-error@-5 {{statement not allowed}}
+#endif
+}