summaryrefslogtreecommitdiffstats
path: root/clang/test/CXX/basic
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-10-01 02:31:28 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-10-01 02:31:28 +0000
commiteb3c10c248ace4100f54e8fb55b7d477d959f222 (patch)
tree2e491475a9d346831848214fba8721e7a53863e7 /clang/test/CXX/basic
parentc5ab7efea372bb2ab025e3a6168766237f9c0de7 (diff)
downloadbcm5719-llvm-eb3c10c248ace4100f54e8fb55b7d477d959f222.tar.gz
bcm5719-llvm-eb3c10c248ace4100f54e8fb55b7d477d959f222.zip
constexpr: semantic checking for constexpr functions and constructors. Based in
part on patches by Peter Collingbourne. We diverge from the C++11 standard in a few areas, mostly related to checking constexpr function declarations, and not just definitions. See WG21 paper N3308=11-0078 for details. Function invocation substitution is not available in this patch; constexpr functions cannot yet be used from within constant expressions. llvm-svn: 140926
Diffstat (limited to 'clang/test/CXX/basic')
-rw-r--r--clang/test/CXX/basic/basic.types/p10.cpp108
1 files changed, 108 insertions, 0 deletions
diff --git a/clang/test/CXX/basic/basic.types/p10.cpp b/clang/test/CXX/basic/basic.types/p10.cpp
new file mode 100644
index 00000000000..66189552350
--- /dev/null
+++ b/clang/test/CXX/basic/basic.types/p10.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+struct NonLiteral { NonLiteral(); };
+
+// A type is a literal type if it is:
+
+// - a scalar type
+constexpr int f1(double);
+
+// - a reference type
+struct S { S(); };
+constexpr int f2(S &);
+
+// - a class type that has all of the following properties:
+
+// - it has a trivial destructor
+struct UserProvDtor {
+ constexpr UserProvDtor(); // expected-error {{non-literal type 'UserProvDtor' cannot have constexpr members}}
+ ~UserProvDtor(); // expected-note {{has a user-provided destructor}}
+};
+struct NonTrivDtor {
+ constexpr NonTrivDtor(); // expected-error {{non-literal type 'NonTrivDtor' cannot have constexpr members}}
+ virtual ~NonTrivDtor() = default; // expected-note {{has a non-trivial destructor}}
+};
+struct NonTrivDtorBase {
+ ~NonTrivDtorBase();
+};
+template<typename T>
+struct DerivedFromNonTrivDtor : T { // expected-note {{'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not literal because it has base class 'NonTrivDtorBase' of non-literal type}}
+ constexpr DerivedFromNonTrivDtor();
+};
+constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>); // expected-error {{constexpr function's 1st parameter type 'DerivedFromNonTrivDtor<NonTrivDtorBase>' is not a literal type}}
+struct TrivDtor {
+ constexpr TrivDtor();
+};
+// FIXME: when building DefinitionData we look at 'isUserProvided' before it's set up!
+#if 0
+struct TrivDefaultedDtor {
+ constexpr TrivDefaultedDtor();
+ ~TrivDefaultedDtor() = default;
+};
+#endif
+
+// - it is an aggregate type or has at least one constexpr constructor or
+// constexpr constructor template that is not a copy or move constructor
+struct Agg {
+ int a;
+ char *b;
+};
+constexpr int f3(Agg a) { return a.a; }
+struct CtorTemplate {
+ template<typename T> constexpr CtorTemplate(T);
+};
+struct CopyCtorOnly { // expected-note {{'CopyCtorOnly' is not literal because it is not an aggregate and has no constexpr constructors other than copy or move constructors}}
+ constexpr CopyCtorOnly(CopyCtorOnly&); // expected-error {{non-literal type 'CopyCtorOnly' cannot have constexpr members}}
+};
+struct MoveCtorOnly { // expected-note {{no constexpr constructors other than copy or move constructors}}
+ constexpr MoveCtorOnly(MoveCtorOnly&&); // expected-error {{non-literal type 'MoveCtorOnly' cannot have constexpr members}}
+};
+template<typename T>
+struct CtorArg { // expected-note {{no constexpr constructors other than copy or move constructors}}
+ constexpr CtorArg(T); // expected-note {{constructor template instantiation is not constexpr because 1st parameter type 'NonLiteral' is not a literal type}}
+};
+constexpr int f(CtorArg<int>);
+constexpr int f(CtorArg<NonLiteral>); // expected-error {{not a literal type}}
+// We have a special-case diagnostic for classes with virtual base classes.
+struct VBase {};
+struct HasVBase : virtual VBase {}; // expected-note 2{{virtual base class declared here}}
+struct Derived : HasVBase {
+ constexpr Derived(); // expected-error {{constexpr constructor not allowed in struct with virtual base class}}
+};
+template<typename T> struct DerivedFromVBase : T { // expected-note {{struct with virtual base class is not a literal type}}
+ constexpr DerivedFromVBase();
+};
+constexpr int f(DerivedFromVBase<HasVBase>); // expected-error {{constexpr function's 1st parameter type 'DerivedFromVBase<HasVBase>' is not a literal type}}
+
+// - it has all non-static data members and base classes of literal types
+struct NonLitMember {
+ S s; // expected-note {{has data member 's' of non-literal type 'S'}}
+};
+constexpr int f(NonLitMember); // expected-error {{1st parameter type 'NonLitMember' is not a literal type}}
+struct NonLitBase :
+ S { // expected-note {{base class 'S' of non-literal type}}
+ constexpr NonLitBase(); // expected-error {{non-literal type 'NonLitBase' cannot have constexpr members}}
+};
+struct LitMemBase : Agg {
+ Agg agg;
+};
+template<typename T>
+struct MemberType {
+ T t; // expected-note {{'MemberType<NonLiteral>' is not literal because it has data member 't' of non-literal type 'NonLiteral'}}
+ constexpr MemberType();
+};
+constexpr int f(MemberType<int>);
+constexpr int f(MemberType<NonLiteral>); // expected-error {{not a literal type}}
+
+// - an array of literal type
+struct ArrGood {
+ Agg agg[24];
+ double d[12];
+ TrivDtor td[3];
+};
+constexpr int f(ArrGood);
+
+struct ArrBad {
+ S s[3]; // expected-note {{data member 's' of non-literal type 'S [3]'}}
+};
+constexpr int f(ArrBad); // expected-error {{1st parameter type 'ArrBad' is not a literal type}}
OpenPOWER on IntegriCloud