diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-19 06:19:21 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-19 06:19:21 +0000 |
commit | d0b4dd656d11d60855bf5b78c7059a3a6c5724d4 (patch) | |
tree | 35d257022b6b7e00a6cf5e0cc038a8a1c7b588ac /clang/test | |
parent | dec792ebb5de0a6b9ff7b9f5ae25682c7031e529 (diff) | |
download | bcm5719-llvm-d0b4dd656d11d60855bf5b78c7059a3a6c5724d4.tar.gz bcm5719-llvm-d0b4dd656d11d60855bf5b78c7059a3a6c5724d4.zip |
constexpr handling improvements. Produce detailed diagnostics when a 'constexpr'
variable is initialized by a non-constant expression, and pass in the variable
being declared so that earlier-initialized fields' values can be used.
Rearrange VarDecl init evaluation to make this possible, and in so doing fix a
long-standing issue in our C++ constant expression handling, where we would
mishandle cases like:
extern const int a;
const int n = a;
const int a = 5;
int arr[n];
Here, n is not initialized by a constant expression, so can't be used in an ICE,
even though the initialization expression would be an ICE if it appeared later
in the TU. This requires computing whether the initializer is an ICE eagerly,
and saving that information in PCH files.
llvm-svn: 146856
Diffstat (limited to 'clang/test')
-rw-r--r-- | clang/test/CXX/basic/basic.types/p10.cpp | 9 | ||||
-rw-r--r-- | clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p1.cpp | 21 | ||||
-rw-r--r-- | clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp | 14 | ||||
-rw-r--r-- | clang/test/CXX/expr/expr.const/p2-0x.cpp | 10 | ||||
-rw-r--r-- | clang/test/PCH/cxx-constexpr.cpp | 19 | ||||
-rw-r--r-- | clang/test/SemaCXX/constant-expression-cxx11.cpp | 67 | ||||
-rw-r--r-- | clang/test/SemaCXX/constant-expression.cpp | 13 | ||||
-rw-r--r-- | clang/test/SemaCXX/constexpr-depth.cpp | 6 | ||||
-rw-r--r-- | clang/test/SemaCXX/constexpr-printing.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx0x-class.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaCXX/i-c-e-cxx.cpp | 4 |
11 files changed, 99 insertions, 77 deletions
diff --git a/clang/test/CXX/basic/basic.types/p10.cpp b/clang/test/CXX/basic/basic.types/p10.cpp index 1f66e5522df..725be09c085 100644 --- a/clang/test/CXX/basic/basic.types/p10.cpp +++ b/clang/test/CXX/basic/basic.types/p10.cpp @@ -34,13 +34,12 @@ constexpr int f(DerivedFromNonTrivDtor<NonTrivDtorBase>); // expected-error {{co struct TrivDtor { constexpr TrivDtor(); }; -// FIXME: when building DefinitionData we look at 'isUserProvided' before it's set up! -#if 0 +constexpr int f(TrivDtor); struct TrivDefaultedDtor { constexpr TrivDefaultedDtor(); ~TrivDefaultedDtor() = default; }; -#endif +constexpr int f(TrivDefaultedDtor); // - it is an aggregate type or has at least one constexpr constructor or // constexpr constructor template that is not a copy or move constructor @@ -100,6 +99,7 @@ struct ArrGood { Agg agg[24]; double d[12]; TrivDtor td[3]; + TrivDefaultedDtor tdd[3]; }; constexpr int f(ArrGood); @@ -120,8 +120,7 @@ namespace MutableMembers { // Here's one reason why allowing this would be a disaster... template<int n> struct Id { int k = n; }; int f() { - // FIXME: correctly check whether the initializer is a constant expression. - constexpr MM m = { 0 }; // desired-error {{must be a constant expression}} + constexpr MM m = { 0 }; // expected-error {{must be initialized by a constant expression}} expected-note {{non-literal type 'const MutableMembers::MM' cannot be used in a constant expression}} ++m.n; return Id<m.n>().k; // expected-error {{not an integral constant expression}} } 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 3f6f160221d..0fb6f7def00 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 @@ -20,7 +20,7 @@ constexpr int s1::mi2 = 0; // not a definition of an object constexpr extern int i2; // expected-error {{constexpr variable declaration must be a definition}} // not a literal type -constexpr notlit nl1; // expected-error {{constexpr variable 'nl1' must be initialized by a constant expression}} +constexpr notlit nl1; // expected-error {{constexpr variable 'nl1' must be initialized by a constant expression}} expected-note {{non-literal type 'const notlit' cannot be used in a constant expression}} // function parameters void f2(constexpr int i) {} // expected-error {{function parameter cannot be constexpr}} // non-static member @@ -42,12 +42,13 @@ 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}} -constexpr class C3 {} c3 = C3(); -constexpr struct S3 {} s3 = S3(); +// 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 union U3 {} u3 = {}; constexpr enum E3 { V3 } e3 = V3; -class C4 {} constexpr c4 = C4(); -struct S4 {} constexpr s4 = S4(); +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}} union U4 {} constexpr u4 = {}; enum E4 { V4 } constexpr e4 = V4; constexpr int; // expected-error {{constexpr can only be used in variable and function declarations}} @@ -67,7 +68,7 @@ struct ConstexprDtor { }; // template stuff -template <typename T> constexpr T ft(T t) { return t; } +template <typename T> constexpr T ft(T t) { return t; } // unexpected-note {{here}} template <typename T> T gt(T t) { return t; } struct S { template<typename T> constexpr T f(); @@ -89,7 +90,7 @@ template <> char S::g() { return 0; } // expected-error {{no function template m template <> double S::g() const { return 0; } // ok // FIXME: The initializer is a constant expression. -constexpr int i3 = ft(1); // unexpected-error {{must be initialized by a constant expression}} +constexpr int i3 = ft(1); // unexpected-error {{must be initialized by a constant expression}} unexpected-note {{undefined function 'ft<int>'}} void test() { // ignore constexpr when instantiating with non-literal @@ -98,7 +99,7 @@ void test() { } // Examples from the standard: -constexpr int square(int x); +constexpr int square(int x); // expected-note {{declared here}} constexpr int bufsz = 1024; constexpr struct pixel { // expected-error {{struct cannot be marked constexpr}} @@ -108,10 +109,10 @@ constexpr struct pixel { // expected-error {{struct cannot be marked constexpr}} }; constexpr pixel::pixel(int a) - : x(square(a)), y(square(a)) + : x(square(a)), y(square(a)) // expected-note {{undefined function 'square' cannot be used in a constant expression}} { } -constexpr pixel small(2); // expected-error {{must be initialized by a constant expression}} +constexpr pixel small(2); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to 'pixel(2)'}} constexpr int square(int x) { return x * x; diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp index fe79a0e6fc1..4145e9b2245 100644 --- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p9.cpp @@ -18,17 +18,17 @@ extern int (*const d)(int); // A variable declaration which uses the constexpr specifier shall have an // initializer and shall be initialized by a constant expression. constexpr int ni1; // expected-error {{default initialization of an object of const type 'const int'}} -constexpr struct C { C(); } ni2; // expected-error {{constexpr variable 'ni2' must be initialized by a constant expression}} +constexpr struct C { C(); } ni2; // expected-error {{constexpr variable 'ni2' must be initialized by a constant expression}} expected-note {{non-literal type 'const struct C' cannot be used in a constant expression}} constexpr double &ni3; // expected-error {{declaration of reference variable 'ni3' requires an initializer}} constexpr int nc1 = i; // expected-error {{constexpr variable 'nc1' must be initialized by a constant expression}} -constexpr C nc2 = C(); // expected-error {{constexpr variable 'nc2' must be initialized by a constant expression}} -int &f(); -constexpr int &nc3 = f(); // expected-error {{constexpr variable 'nc3' must be initialized by a constant expression}} +constexpr C nc2 = C(); // expected-error {{constexpr variable 'nc2' must be initialized by a constant expression}} expected-note {{non-literal type}} +int &f(); // expected-note {{declared here}} +constexpr int &nc3 = f(); // expected-error {{constexpr variable 'nc3' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f' cannot be used in a constant expression}} constexpr int nc4(i); // expected-error {{constexpr variable 'nc4' must be initialized by a constant expression}} -constexpr C nc5((C())); // expected-error {{constexpr variable 'nc5' must be initialized by a constant expression}} -int &f(); -constexpr int &nc6(f()); // expected-error {{constexpr variable 'nc6' must be initialized by a constant expression}} +constexpr C nc5((C())); // expected-error {{constexpr variable 'nc5' must be initialized by a constant expression}} expected-note {{non-literal type 'const C'}} +int &f(); // expected-note {{here}} +constexpr int &nc6(f()); // expected-error {{constexpr variable 'nc6' must be initialized by a constant expression}} expected-note {{non-constexpr function 'f'}} struct pixel { int x, y; diff --git a/clang/test/CXX/expr/expr.const/p2-0x.cpp b/clang/test/CXX/expr/expr.const/p2-0x.cpp index d02db92a263..aa83fc7fa99 100644 --- a/clang/test/CXX/expr/expr.const/p2-0x.cpp +++ b/clang/test/CXX/expr/expr.const/p2-0x.cpp @@ -78,13 +78,13 @@ namespace NonConstExprReturn { namespace NonConstExprCtor { struct T { constexpr T(const int &r) : - r(r) { // expected-note {{reference to temporary cannot be used to initialize a member in a constant expression}} + r(r) { // expected-note 2{{reference to temporary cannot be used to initialize a member in a constant expression}} } const int &r; }; constexpr int n = 0; constexpr T t1(n); // ok - constexpr T t2(0); // expected-error {{must be initialized by a constant expression}} + constexpr T t2(0); // expected-error {{must be initialized by a constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'T(0)'}} struct S { int n : T(4).r; // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'T(4)'}} @@ -187,8 +187,8 @@ namespace References { constexpr int e = 42; int &f = const_cast<int&>(e); extern int &g; - constexpr int &h(); // expected-note {{here}} - int &i = h(); + constexpr int &h(); // expected-note 2{{here}} + int &i = h(); // expected-note {{here}} expected-note {{undefined function 'h' cannot be used in a constant expression}} constexpr int &j() { return b; } int &k = j(); @@ -202,7 +202,7 @@ namespace References { int F : f - 11; int G : g; // expected-error {{constant expression}} int H : h(); // expected-error {{constant expression}} expected-note {{undefined function 'h'}} - int I : i; // expected-error {{constant expression}} + int I : i; // expected-error {{constant expression}} expected-note {{initializer of 'i' is not a constant expression}} int J : j(); int K : k; }; diff --git a/clang/test/PCH/cxx-constexpr.cpp b/clang/test/PCH/cxx-constexpr.cpp new file mode 100644 index 00000000000..8fe48f7377e --- /dev/null +++ b/clang/test/PCH/cxx-constexpr.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 -pedantic-errors -std=c++98 -emit-pch %s -o %t +// RUN: %clang_cc1 -pedantic-errors -std=c++98 -include-pch %t -verify %s + +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t-cxx11 +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -include-pch %t-cxx11 -verify %s + +#ifndef HEADER_INCLUDED + +#define HEADER_INCLUDED +extern const int a; +const int b = a; + +#else + +const int a = 5; +typedef int T[b]; // expected-error {{variable length array}} expected-error {{must be an integer constant expression}} +typedef int T[5]; + +#endif 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}} } } |