summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaCXX
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaCXX')
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp67
-rw-r--r--clang/test/SemaCXX/constant-expression.cpp13
-rw-r--r--clang/test/SemaCXX/constexpr-depth.cpp6
-rw-r--r--clang/test/SemaCXX/constexpr-printing.cpp9
-rw-r--r--clang/test/SemaCXX/cxx0x-class.cpp4
-rw-r--r--clang/test/SemaCXX/i-c-e-cxx.cpp4
6 files changed, 53 insertions, 50 deletions
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 5b053e4ce67..94da73fcf6a 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -8,9 +8,7 @@ static_assert(false, "test"); // expected-error {{test}}
}
-// FIXME: support const T& parameters here.
-//template<typename T> constexpr T id(const T &t) { return t; }
-template<typename T> constexpr T id(T t) { return t; } // expected-note {{here}}
+template<typename T> constexpr T id(const T &t) { return t; } // expected-note {{here}}
// FIXME: support templates here.
//template<typename T> constexpr T min(const T &a, const T &b) {
// return a < b ? a : b;
@@ -104,8 +102,14 @@ namespace CaseStatements {
}
extern int &Recurse1;
-int &Recurse2 = Recurse1, &Recurse1 = Recurse2;
-constexpr int &Recurse3 = Recurse2; // expected-error {{must be initialized by a constant expression}}
+int &Recurse2 = Recurse1; // expected-note 2{{declared here}} expected-note {{initializer of 'Recurse1' is not a constant expression}}
+int &Recurse1 = Recurse2; // expected-note {{declared here}} expected-note {{initializer of 'Recurse2' is not a constant expression}}
+constexpr int &Recurse3 = Recurse2; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'Recurse2' is not a constant expression}}
+
+extern const int RecurseA;
+const int RecurseB = RecurseA; // expected-note {{declared here}}
+const int RecurseA = 10;
+constexpr int RecurseC = RecurseB; // expected-error {{must be initialized by a constant expression}} expected-note {{initializer of 'RecurseB' is not a constant expression}}
namespace MemberEnum {
struct WithMemberEnum {
@@ -188,26 +192,26 @@ namespace StaticMemberFunction {
namespace ParameterScopes {
const int k = 42;
- constexpr const int &ObscureTheTruth(const int &a) { return a; }
- constexpr const int &MaybeReturnJunk(bool b, const int a) {
- return ObscureTheTruth(b ? a : k);
+ constexpr const int &ObscureTheTruth(const int &a) { return a; } // expected-note 3{{reference to 'a' cannot be returned from a constexpr function}}
+ constexpr const int &MaybeReturnJunk(bool b, const int a) { // expected-note 2{{declared here}}
+ return ObscureTheTruth(b ? a : k); // expected-note 2{{in call to 'ObscureTheTruth(a)'}}
}
static_assert(MaybeReturnJunk(false, 0) == 42, ""); // ok
- constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}}
+ constexpr int a = MaybeReturnJunk(true, 0); // expected-error {{constant expression}} expected-note {{in call to 'MaybeReturnJunk(1, 0)'}}
- constexpr const int MaybeReturnNonstaticRef(bool b, const int a) {
+ constexpr const int MaybeReturnNonstaticRef(bool b, const int a) { // expected-note {{here}}
// If ObscureTheTruth returns a reference to 'a', the result is not a
// constant expression even though 'a' is still in scope.
- return ObscureTheTruth(b ? a : k);
+ return ObscureTheTruth(b ? a : k); // expected-note {{in call to 'ObscureTheTruth(a)'}}
}
static_assert(MaybeReturnNonstaticRef(false, 0) == 42, ""); // ok
- constexpr int b = MaybeReturnNonstaticRef(true, 0); // expected-error {{constant expression}}
+ constexpr int b = MaybeReturnNonstaticRef(true, 0); // expected-error {{constant expression}} expected-note {{in call to 'MaybeReturnNonstaticRef(1, 0)'}}
constexpr int InternalReturnJunk(int n) {
// FIXME: We should reject this: it never produces a constant expression.
- return MaybeReturnJunk(true, n);
+ return MaybeReturnJunk(true, n); // expected-note {{in call to 'MaybeReturnJunk(1, 0)'}}
}
- constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}}
+ constexpr int n3 = InternalReturnJunk(0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'InternalReturnJunk(0)'}}
constexpr int LToR(int &n) { return n; }
constexpr int GrabCallersArgument(bool which, int a, int b) {
@@ -243,11 +247,11 @@ namespace FunctionPointers {
constexpr auto Select(int n) -> int (*)(int) {
return n == 2 ? &Double : n == 3 ? &Triple : n == 4 ? &Quadruple : 0;
}
- constexpr int Apply(int (*F)(int), int n) { return F(n); }
+ constexpr int Apply(int (*F)(int), int n) { return F(n); } // expected-note {{subexpression}}
static_assert(1 + Apply(Select(4), 5) + Apply(Select(3), 7) == 42, "");
- constexpr int Invalid = Apply(Select(0), 0); // expected-error {{must be initialized by a constant expression}}
+ constexpr int Invalid = Apply(Select(0), 0); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'Apply(0, 0)'}}
}
@@ -293,9 +297,7 @@ static_assert(&x < &x, "false"); // expected-error {{false}}
static_assert(&x > &x, "false"); // expected-error {{false}}
constexpr S* sptr = &s;
-// FIXME: This is not a constant expression; check we reject this and move this
-// test elsewhere.
-constexpr bool dyncast = sptr == dynamic_cast<S*>(sptr);
+constexpr bool dyncast = sptr == dynamic_cast<S*>(sptr); // expected-error {{constant expression}} expected-note {{dynamic_cast}}
struct Str {
// FIXME: In C++ mode, we should say 'integral' not 'integer'
@@ -323,8 +325,6 @@ struct Str {
};
extern char externalvar[];
-// FIXME: This is not a constant expression; check we reject this and move this
-// test elsewhere.
constexpr bool constaddress = (void *)externalvar == (void *)0x4000UL; // expected-error {{must be initialized by a constant expression}}
constexpr bool litaddress = "foo" == "foo"; // expected-error {{must be initialized by a constant expression}} expected-warning {{unspecified}}
static_assert(0 != "foo", "");
@@ -509,21 +509,17 @@ struct D {
};
static_assert(D().c.n == 42, "");
-struct E {
- constexpr E() : p(&p) {}
+struct E { // expected-note {{here}}
+ 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}}
+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.
-// We notice this when evaluating an expression which uses it, but not when
-// checking its initializer.
-constexpr E e2 = E(); // unexpected-error {{constant expression}}
-static_assert(e2.p == &e2.p, ""); // unexpected-error {{constant expression}} unexpected-note {{subexpression}}
-// FIXME: We don't pass through the fact that 'this' is ::e3 when checking the
-// initializer of this declaration.
-constexpr E e3; // unexpected-error {{constant expression}}
+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 e3;
static_assert(e3.p == &e3.p, "");
extern const class F f;
@@ -531,7 +527,7 @@ struct F {
constexpr F() : p(&f.p) {}
const void *p;
};
-constexpr F f = F();
+constexpr F f;
struct G {
struct T {
@@ -624,10 +620,7 @@ struct Base : Bottom {
struct Base2 : Bottom {
constexpr Base2(const int &r) : r(r) {}
int q = 123;
- // FIXME: When we track the global for which we are computing the initializer,
- // use a reference here.
- //const int &r;
- int r;
+ const int &r;
};
struct Derived : Base, Base2 {
constexpr Derived() : Base(76), Base2(a) {}
@@ -646,7 +639,7 @@ static_assert(derived.b[2] == 's', "");
static_assert(derived.c == 76 + 'e', "");
static_assert(derived.q == 123, "");
static_assert(derived.r == 76, "");
-static_assert(&derived.r == &derived.a, ""); // expected-error {{}}
+static_assert(&derived.r == &derived.a, "");
static_assert(!(derived == base), "");
static_assert(derived == base2, "");
diff --git a/clang/test/SemaCXX/constant-expression.cpp b/clang/test/SemaCXX/constant-expression.cpp
index 0367cc55468..061e77591b1 100644
--- a/clang/test/SemaCXX/constant-expression.cpp
+++ b/clang/test/SemaCXX/constant-expression.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s
// C++ [expr.const]p1:
// In several places, C++ requires expressions that evaluate to an integral
// or enumeration constant: as array bounds, as case expressions, as
@@ -103,8 +103,17 @@ namespace IntOrEnum {
S<p> s; // expected-error {{not an integral constant expression}}
}
+extern const int recurse1;
+// recurse2 cannot be used in a constant expression because it is not
+// initialized by a constant expression. The same expression appearing later in
+// the TU would be a constant expression, but here it is not.
+const int recurse2 = recurse1;
+const int recurse1 = 1;
+int array1[recurse1]; // ok
+int array2[recurse2]; // expected-warning {{variable length array}} expected-warning {{integer constant expression}}
+
namespace FloatConvert {
typedef int a[(int)42.3];
typedef int a[(int)42.997];
- typedef int b[(int)4e10]; // expected-error {{variable length}}
+ typedef int b[(int)4e10]; // expected-warning {{variable length}} expected-error {{variable length}}
}
diff --git a/clang/test/SemaCXX/constexpr-depth.cpp b/clang/test/SemaCXX/constexpr-depth.cpp
index b8ae6682c56..feba6fde3fb 100644
--- a/clang/test/SemaCXX/constexpr-depth.cpp
+++ b/clang/test/SemaCXX/constexpr-depth.cpp
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -DMAX=128 -fconstexpr-depth 128
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -DMAX=1 -fconstexpr-depth 1
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -DMAX=2 -fconstexpr-depth 2
// RUN: %clang -std=c++11 -fsyntax-only -Xclang -verify %s -DMAX=10 -fconstexpr-depth=10
-constexpr int depth(int n) { return n > 1 ? depth(n-1) : 0; }
+constexpr int depth(int n) { return n > 1 ? depth(n-1) : 0; } // expected-note {{exceeded maximum depth}} expected-note +{{}}
-constexpr int kBad = depth(MAX + 1); // expected-error {{must be initialized by a constant expression}}
+constexpr int kBad = depth(MAX + 1); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'depth(}}
constexpr int kGood = depth(MAX);
diff --git a/clang/test/SemaCXX/constexpr-printing.cpp b/clang/test/SemaCXX/constexpr-printing.cpp
index 341495ccecd..726d1770fae 100644
--- a/clang/test/SemaCXX/constexpr-printing.cpp
+++ b/clang/test/SemaCXX/constexpr-printing.cpp
@@ -1,18 +1,19 @@
// RUN: %clang_cc1 %s -std=c++11 -fsyntax-only -verify
-constexpr int extract(struct S &s);
+struct S;
+constexpr int extract(const S &s);
struct S {
- constexpr S() : n(extract(*this)), m(0) {}
+ constexpr S() : n(extract(*this)), m(0) {} // expected-note {{in call to 'extract(s1)'}}
constexpr S(int k) : n(k), m(extract(*this)) {}
int n, m;
};
-constexpr int extract(S &s) { return s.n; }
+constexpr int extract(const S &s) { return s.n; } // expected-note {{subexpression}}
// FIXME: once we produce notes for constexpr variable declarations, this should
// produce a note indicating that S.n is used uninitialized.
-constexpr S s1; // expected-error {{constant expression}}
+constexpr S s1; // expected-error {{constant expression}} expected-note {{in call to 'S()'}}
constexpr S s2(10);
typedef __attribute__((vector_size(16))) int vector_int;
diff --git a/clang/test/SemaCXX/cxx0x-class.cpp b/clang/test/SemaCXX/cxx0x-class.cpp
index 3527ccb5557..2ceacfc9b2f 100644
--- a/clang/test/SemaCXX/cxx0x-class.cpp
+++ b/clang/test/SemaCXX/cxx0x-class.cpp
@@ -17,12 +17,12 @@ public:
};
namespace rdar8367341 {
- float foo();
+ float foo(); // expected-note {{here}}
struct A {
static const float x = 5.0f; // expected-warning {{GNU extension}} expected-note {{use 'constexpr' specifier to silence this warning}}
static const float y = foo(); // expected-warning {{GNU extension}} expected-note {{use 'constexpr' specifier to silence this warning}} expected-error {{in-class initializer is not a constant expression}}
static constexpr float x2 = 5.0f;
- static constexpr float y2 = foo(); // expected-error {{must be initialized by a constant expression}}
+ static constexpr float y2 = foo(); // expected-error {{must be initialized by a constant expression}} expected-note {{non-constexpr function 'foo'}}
};
}
diff --git a/clang/test/SemaCXX/i-c-e-cxx.cpp b/clang/test/SemaCXX/i-c-e-cxx.cpp
index ba60054f2e0..eae354814b5 100644
--- a/clang/test/SemaCXX/i-c-e-cxx.cpp
+++ b/clang/test/SemaCXX/i-c-e-cxx.cpp
@@ -16,9 +16,9 @@ void f() {
}
int a() {
- const int t=t;
+ const int t=t; // expected-note {{declared here}}
switch(1) { // expected-warning {{no case matching constant switch condition '1'}}
- case t:; // expected-error {{not an integer constant expression}}
+ case t:; // expected-error {{not an integer constant expression}} expected-note {{initializer of 't' is not a constant expression}}
}
}
OpenPOWER on IntegriCloud