@@ -2165,7 +2165,33 @@ modifying_const_object_error (tree expr, tree obj)
auto_diagnostic_group d;
error_at (loc, "modifying a const object %qE is not allowed in "
"a constant expression", TREE_OPERAND (expr, 0));
- inform (location_of (obj), "originally declared %<const%> here");
+
+ /* Find the underlying object that was declared as const. */
+ location_t decl_loc = UNKNOWN_LOCATION;
+ for (tree probe = obj; decl_loc == UNKNOWN_LOCATION; )
+ switch (TREE_CODE (probe))
+ {
+ case BIT_FIELD_REF:
+ case COMPONENT_REF:
+ {
+ tree elt = TREE_OPERAND (probe, 1);
+ if (CP_TYPE_CONST_P (TREE_TYPE (elt)))
+ decl_loc = DECL_SOURCE_LOCATION (elt);
+ probe = TREE_OPERAND (probe, 0);
+ }
+ break;
+
+ case ARRAY_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ probe = TREE_OPERAND (probe, 0);
+ break;
+
+ default:
+ decl_loc = location_of (probe);
+ break;
+ }
+ inform (decl_loc, "originally declared %<const%> here");
}
/* Return true if FNDECL is a replaceable global allocation function that
@@ -6286,6 +6312,21 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
if (TREE_CODE (init) == TARGET_EXPR)
if (tree tinit = TARGET_EXPR_INITIAL (init))
init = tinit;
+
+ /* Improve error messages for initialisers when the initialising
+ expression has no location information by pointing to the decl
+ that is getting initialised. */
+ location_t target_loc = cp_expr_loc_or_input_loc (init);
+ if (!EXPR_HAS_LOCATION (init))
+ {
+ if (DECL_P (target))
+ target_loc = DECL_SOURCE_LOCATION (target);
+ else if (TREE_CODE (target) == COMPONENT_REF
+ || TREE_CODE (target) == BIT_FIELD_REF)
+ target_loc = DECL_SOURCE_LOCATION (TREE_OPERAND (target, 1));
+ }
+ iloc_sentinel sentinel = target_loc;
+
init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
non_constant_p, overflow_p);
/* The hash table might have moved since the get earlier, and the
@@ -6986,7 +7027,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
return t;
}
+ /* Change the input location to the currently processed expression for
+ better error messages when a subexpression has no location. */
location_t loc = cp_expr_loc_or_input_loc (t);
+ iloc_sentinel sentinel (loc);
STRIP_ANY_LOCATION_WRAPPER (t);
@@ -10,11 +10,11 @@
// R() is well-formed because i is initialized before j.
struct s {
- constexpr s() : v(v) { }
+ constexpr s() : v(v) { } // { dg-error "accessing uninitialized member" }
int v;
};
-constexpr s bang; // { dg-error "|" }
+constexpr s bang; // { dg-message "in .constexpr. expansion" }
struct R {
int i,j;
@@ -26,14 +26,14 @@ constexpr R r; // { dg-bogus "" }
// Ill-formed (no diagnostic required)
struct T {
int i;
- constexpr int f() { return i; }
+ constexpr int f() { return i; } // { dg-error "accessing uninitialized member" }
constexpr T(): i(0) { }
- constexpr T(const T& t) : i(f()) { } // { dg-message "" }
+ constexpr T(const T& t) : i(f()) { } // { dg-message "in .constexpr. expansion" }
};
constexpr T t1;
// Ill-formed (diagnostic required)
-constexpr T t2(t1); // { dg-message "" }
+constexpr T t2(t1); // { dg-message "in .constexpr. expansion" }
// Well-formed
struct U {
@@ -1,10 +1,10 @@
// PR c++/70323
// { dg-do compile { target c++11 } }
-constexpr int overflow_if_0 (int i) { return __INT_MAX__ + !i; }
-constexpr int overflow_if_1 (int i) { return __INT_MAX__ + i; }
+constexpr int overflow_if_0 (int i) { return __INT_MAX__ + !i; } // { dg-error "overflow in constant expression" }
+constexpr int overflow_if_1 (int i) { return __INT_MAX__ + i; } // { dg-error "overflow in constant expression" }
-constexpr bool i0_0 = overflow_if_0 (0); // { dg-error "overflow in constant expression|in .constexpr. expansion of " }
+constexpr bool i0_0 = overflow_if_0 (0); // { dg-message "in .constexpr. expansion of " }
constexpr bool i0_1 = overflow_if_0 (1);
constexpr bool i1_0 = overflow_if_1 (0);
-constexpr bool i1_1 = overflow_if_1 (1); // { dg-error "overflow in constant expression|in .constexpr. expansion of " }
+constexpr bool i1_1 = overflow_if_1 (1); // { dg-message "in .constexpr. expansion of " }
@@ -2,10 +2,10 @@
// { dg-do compile { target c++11 } }
// { dg-options "-Wall" }
-constexpr int overflow_if_0 (int i) { return __INT_MAX__ + !i; }
-constexpr int overflow_if_1 (int i) { return __INT_MAX__ + i; }
+constexpr int overflow_if_0 (int i) { return __INT_MAX__ + !i; } // { dg-error "overflow in constant expression" }
+constexpr int overflow_if_1 (int i) { return __INT_MAX__ + i; } // { dg-error "overflow in constant expression" }
-constexpr bool i0_0 = overflow_if_0 (0); // { dg-error "overflow in constant expression|in .constexpr. expansion of" }
+constexpr bool i0_0 = overflow_if_0 (0); // { dg-message "in .constexpr. expansion of" }
constexpr bool i0_1 = overflow_if_0 (1);
constexpr bool i1_0 = overflow_if_1 (0);
-constexpr bool i1_1 = overflow_if_1 (1); // { dg-error "overflow in constant expression|in .constexpr. expansion of" }
+constexpr bool i1_1 = overflow_if_1 (1); // { dg-message "in .constexpr. expansion of" }
@@ -6,8 +6,9 @@ constexpr int f(int i) { return i; }
constexpr int g(A* ap)
{
return f((delete[] ap, 42)); // { dg-message "" "" { target c++17_down } }
+ // { dg-error "" "" { target c++2a } .-1 }
}
A a;
-constexpr int i = g(&a); // { dg-error "" }
- // { dg-message "in 'constexpr' expansion of" "" { target c++2a } .-1 }
+constexpr int i = g(&a); // { dg-error "" "" { target c++17_down } }
+ // { dg-message "in 'constexpr' expansion of" "" { target c++2a } .-1 }
@@ -16,7 +16,7 @@ int main()
struct complex // { dg-message "no .constexpr. constructor" "" { target { ! implicit_constexpr } } }
{
complex(double r, double i) : re(r), im(i) { }
- constexpr double real() const { return re; } // { dg-error "not a literal type" "" { target c++11_only } }
+ constexpr double real() const { return re; } // { dg-error "not a literal type|not usable in a constant expression" "" { target { ! implicit_constexpr } } }
double imag() const { return im; }
private:
@@ -3,5 +3,6 @@
typedef bool (*Function)(int);
constexpr bool check(int x, Function p) { return p(x); } // { dg-message "in .constexpr. expansion of" }
+// { dg-error "not a constant expression" "" { target *-*-* } .-1 }
static_assert(check(2, check), ""); // { dg-error "conversion|constant|in .constexpr. expansion of" }
@@ -1,6 +1,6 @@
// Test that we catch excessive recursion.
// { dg-do compile { target c++11 } }
// { dg-options "-fconstexpr-depth=5" }
-// { dg-prune-output "in constexpr expansion" }
-constexpr int f (int i) { return f (i-1); } // { dg-message "in .constexpr. expansion of " }
-constexpr int i = f(42); // { dg-error ".constexpr. evaluation depth|in .constexpr. expansion of " }
+// { dg-prune-output "in .constexpr. expansion" }
+constexpr int f (int i) { return f (i-1); } // { dg-error ".constexpr. evaluation depth" }
+constexpr int i = f(42);
@@ -4,7 +4,7 @@ template <long long i>
struct Fib
{
static const long long value // { dg-error "overflow" }
- = Fib<i-1>::value + Fib<i-2>::value;
+ = Fib<i-1>::value + Fib<i-2>::value; // { dg-error "overflow" }
};
template <>
@@ -14,7 +14,8 @@ struct B {
}
};
struct C : A {
- B bar {this};
+ B bar {this}; // { dg-error "" "" { target c++14_down } }
};
-constexpr C foo {}; // { dg-message "" }
+// error path changes in C++17 due to `C` becoming an aggregate
+constexpr C foo {}; // { dg-error "" "" { target c++17 } }
@@ -6,7 +6,7 @@ foo ()
{
union U { long long a; int b[2]; } u { 5LL };
u.b[1] = 4; // { dg-error "change of the active member of a union from" "" { target c++17_down } }
- return u.b[0];
+ return u.b[0]; // { dg-error "accessing uninitialized array element" "" { target c++2a } }
}
constexpr int
@@ -19,6 +19,5 @@ bar ()
static_assert (foo () == 0, ""); // { dg-error "non-constant condition for static assertion" }
// { dg-message "in 'constexpr' expansion of" "" { target *-*-* } .-1 }
- // { dg-error "accessing uninitialized array element" "" { target c++2a } .-2 }
static_assert (bar () == 4, ""); // { dg-error "non-constant condition for static assertion" "" { target c++17_down } }
// { dg-message "in 'constexpr' expansion of" "" { target c++17_down } .-1 }
@@ -11,3 +11,4 @@ constexpr const int& test() {
return local.get();
}
constexpr int x = test(); // { dg-error "accessing object outside its lifetime" }
+
@@ -8,9 +8,9 @@ struct S {
constexpr int error() {
const auto& local = S{}.get(); // { dg-message "note: declared here" }
- return local;
+ return local; // { dg-error "accessing object outside its lifetime" }
}
-constexpr int x = error(); // { dg-error "accessing object outside its lifetime" }
+constexpr int x = error(); // { dg-message "in .constexpr. expansion" }
constexpr int ok() {
// temporary should only be destroyed after end of full-expression
@@ -7,7 +7,7 @@ constexpr int f(int i) {
int j = 123; // { dg-message "note: declared here" }
p = &j;
}
- return *p;
+ return *p; // { dg-error "accessing object outside its lifetime" }
}
-constexpr int i = f(0); // { dg-error "accessing object outside its lifetime" }
+constexpr int i = f(0); // { dg-message "in .constexpr. expansion" }
@@ -5,7 +5,7 @@ constexpr const double& test() {
return local;
}
-static_assert(test() == 3.0, ""); // { dg-error "constant|accessing object outside its lifetime" }
+static_assert(test() == 3.0, ""); // { dg-error "non-constant condition|accessing object outside its lifetime" }
// no deference, shouldn't error
static_assert((test(), true), "");
@@ -5,7 +5,7 @@ constexpr const int& id(int x) { return x; } // { dg-message "note: declared he
constexpr bool test() {
const int& y = id(3);
- return y == 3;
+ return y == 3; // { dg-error "accessing object outside its lifetime" }
}
-constexpr bool x = test(); // { dg-error "accessing object outside its lifetime" }
+constexpr bool x = test(); // { dg-message "in .constexpr. expansion" }
@@ -14,7 +14,7 @@ struct C {
struct A {
int r;
- const C c;
+ const C c; // { dg-message "originally declared" }
constexpr A() : r(11) { r = 14; const_cast<C &>(c).n = 42; } // { dg-error "modifying a const object" }
};
@@ -34,5 +34,4 @@ struct B {
};
constexpr B b(false); // { dg-message "in .constexpr. expansion of" }
-// { dg-message "originally declared" "" { target *-*-* } .-1 }
static_assert(b.e.d.a.c.n == 2, ""); // { dg-error "non-constant condition" }
@@ -7,7 +7,7 @@ constexpr int& impl(const int (&array)[10], int index) {
struct A {
constexpr int& operator[](int i) { return impl(elems, i); }
- const int elems[10];
+ const int elems[10]; // { dg-message "originally declared" }
};
constexpr bool
@@ -19,4 +19,3 @@ f()
}
constexpr bool b = f(); // { dg-message "in .constexpr. expansion of " }
-// { dg-message "originally declared" "" { target *-*-* } .-1 }
@@ -13,11 +13,11 @@ struct array
template <typename T>
struct S {
using U = array<T, 4>;
- const U m;
+ const U m; // { dg-message "originally declared" }
constexpr S(int) : m{}
{
const_cast<int &>(const_cast<const U &>(m)[0]) = 42; // { dg-error "modifying a const object" }
}
};
-constexpr S<int> p = { 10 }; // { dg-message "originally declared" }
+constexpr S<int> p = { 10 };
@@ -7,7 +7,7 @@ template <typename E, size_t N>
struct array
{
constexpr const E &operator[](size_t n) const noexcept { return elems[n]; }
- const E elems[N];
+ const E elems[N]; // { dg-message "originally declared" }
};
template <typename T>
@@ -20,4 +20,4 @@ struct S {
}
};
-constexpr S<int> p = { 10 }; // { dg-message "originally declared" }
+constexpr S<int> p = { 10 };
@@ -18,11 +18,11 @@ struct array2 {
template <typename T>
struct S {
using U = array2<T, 4>;
- const U m;
+ const U m; // { dg-message "originally declared" }
constexpr S(int) : m{}
{
const_cast<int &>(m.a[0]) = 42; // { dg-error "modifying a const object" }
}
};
-constexpr S<int> p = { 10 }; // { dg-message "originally declared" }
+constexpr S<int> p = { 10 };
@@ -7,11 +7,11 @@ struct X {
template <typename T>
struct S {
- const X x;
+ const X x; // { dg-message "originally declared" }
constexpr S(int) : x{}
{
const_cast<X&>(x).i = 19; // { dg-error "modifying a const object" }
}
};
-constexpr S<int> p = { 10 }; // { dg-message "originally declared" }
+constexpr S<int> p = { 10 };
@@ -7,7 +7,7 @@ struct A {
};
struct B {
- const A a;
+ const A a; // { dg-message "originally declared" }
constexpr B(bool b) {
if (b)
const_cast<A &>(a).n = 3; // { dg-error "modifying a const object" }
@@ -18,5 +18,4 @@ constexpr B b(false);
static_assert(b.a.n == 2, "");
constexpr B b2(true); // { dg-message "in .constexpr. expansion of " }
-// { dg-message "originally declared" "" { target *-*-* } .-1 }
static_assert((b2.a.n, 1), "");
@@ -2,7 +2,7 @@
// { dg-do compile { target c++14 } }
struct A {
- const int n;
+ const int n; // { dg-message "originally declared" }
constexpr A() : n(1) { }
};
struct B {
@@ -13,5 +13,4 @@ struct B {
}
};
constexpr B b; // { dg-message "in .constexpr. expansion of " }
-// { dg-message "originally declared" "" { target *-*-* } .-1 }
static_assert((b.a.n, 1), "");
@@ -3,7 +3,7 @@
struct D { int n; };
-struct C { const D d; };
+struct C { const D d; }; // { dg-message "originally declared" }
struct A {
C c;
@@ -19,5 +19,4 @@ struct B {
};
constexpr B b{}; // { dg-message "in .constexpr. expansion of " }
-// { dg-message "originally declared" "" { target *-*-* } .-1 }
static_assert((b.a.c.d.n, 1), "");
@@ -8,8 +8,8 @@ union U {
};
constexpr int foo(U *up) {
- up->a++;
+ up->a++; // { dg-error "accessing uninitialized member" }
return {42};
}
-extern constexpr U u = {}; // { dg-error "accessing uninitialized member" }
+extern constexpr U u = {}; // { dg-message "in .constexpr. expansion" }
@@ -6,11 +6,11 @@ typedef float __attribute__( ( vector_size( 16 ) ) ) float32x4_t;
constexpr float32x4_t fill(float x) {
float32x4_t v{0};
constexpr auto vs = sizeof(v)/sizeof(v[0]);
- for (auto i=0U; i<vs; ++i) v[i]=i;
+ for (auto i=0U; i<vs; ++i) v[i]=i; // { dg-error "not a constant" }
return v+x;
}
float32x4_t foo(float32x4_t x) {
- constexpr float32x4_t v = fill(1.f); // { dg-error "not a constant||in .constexpr. expansion of " }
+ constexpr float32x4_t v = fill(1.f); // { dg-message "in .constexpr. expansion of " }
return x+v;
}
@@ -1,7 +1,7 @@
// Testcase from P0170R1
// { dg-do compile { target c++17 } }
-auto monoid = [](auto v) { return [=] { return v; }; };
+auto monoid = [](auto v) { return [=] { return v; }; }; // { dg-error "not usable in a constant expression" }
auto add = [](auto m1) constexpr {
auto ret = m1();
return [=](auto m2) mutable {
@@ -22,7 +22,7 @@ int main()
// member function call operator can not perform an lvalue-to-rvalue conversion
// on one of its subobjects (that represents its capture) in a constant
// expression.
- auto two = monoid(2);
+ auto two = monoid(2); // { dg-message "not declared .constexpr." }
if (!(two() == 2)) __builtin_abort(); // OK, not a constant expression.
static_assert(add(one)(one)() == two()); // { dg-error "|in .constexpr. expansion of " } two() is not a constant expression
static_assert(add(one)(one)() == monoid(2)()); // OK
@@ -4,11 +4,14 @@
auto Fwd = [](int (*fp)(int), auto a) { return fp(a); };
auto C = [](auto a) { return a; };
static_assert( Fwd(C ,3) == 3); // OK
+
// No specialization of the function call operator template can be constexpr
// (because of the local static).
auto NC = [](auto a) { static int s; return a; }; // { dg-error "static" }
-// { dg-message "operator int" "" { target *-*-* } .+1 }
+// { dg-error "called in a constant expression" "" { target *-*-* } .-1 }
+
static_assert( Fwd(NC ,3) == 3); // { dg-error "" }
+// { dg-message "operator int" "" { target *-*-* } .-1 }
// We look for the string "operator int" to check that we aren't trying to do
// template pretty-printing in an expression; that gets incredibly unwieldy
@@ -28,7 +28,7 @@ f3 ()
{
T t = { 1, 2 };
S s = __builtin_bit_cast (S, t);
- return s.a[1] == 0;
+ return s.a[1] == 0; // { dg-error "accessing uninitialized array element" }
}
constexpr bool
@@ -52,12 +52,12 @@ f6 ()
{
W t = { 1, 2 };
V s = __builtin_bit_cast (V, t);
- return s.b.a[1] == 1;
+ return s.b.a[1] == 1; // { dg-error "accessing uninitialized array element" }
}
constexpr bool a = f1 ();
constexpr bool b = f2 ();
-constexpr bool c = f3 (); // { dg-error "accessing uninitialized array element" }
-constexpr bool d = f4 ();
+constexpr bool c = f3 (); // { dg-message "in .constexpr. expansion" }
+constexpr bool d = f4 (); // { dg-message "in .constexpr. expansion" }
constexpr bool e = f5 ();
-constexpr bool f = f6 (); // { dg-error "accessing uninitialized array element" }
+constexpr bool f = f6 (); // { dg-message "in .constexpr. expansion" }
@@ -33,7 +33,7 @@ f3 ()
{
T t = { 1, 2 };
S s = __builtin_bit_cast (S, t);
- return s.a[1] == 0;
+ return s.a[1] == 0; // { dg-error "accessing uninitialized array element" }
}
constexpr bool
@@ -57,12 +57,12 @@ f6 ()
{
W t = { 1, 2 };
V s = __builtin_bit_cast (V, t);
- return s.b.a[1] == 1;
+ return s.b.a[1] == 1; // { dg-error "accessing uninitialized array element" }
}
constexpr bool a = f1 ();
constexpr bool b = f2 ();
-constexpr bool c = f3 (); // { dg-error "accessing uninitialized array element" }
-constexpr bool d = f4 ();
+constexpr bool c = f3 (); // { dg-message "in .constexpr. expansion" }
+constexpr bool d = f4 (); // { dg-message "in .constexpr. expansion" }
constexpr bool e = f5 ();
-constexpr bool f = f6 (); // { dg-error "accessing uninitialized array element" }
+constexpr bool f = f6 (); // { dg-message "in .constexpr. expansion" }
@@ -44,7 +44,7 @@ f5 ()
{
T1 t = { 0, 0, 0, 0, 0, 0, 0 };
S s = __builtin_bit_cast (S, t);
- unsigned char a = s.a;
+ unsigned char a = s.a; // { dg-error "accessing uninitialized member" }
return true;
}
@@ -53,7 +53,7 @@ f6 ()
{
T2 t = { 0, 0, 0, 0, 0, 0, 0 };
S s = __builtin_bit_cast (S, t);
- unsigned char b = s.b;
+ unsigned char b = s.b; // { dg-error "accessing uninitialized member" }
return true;
}
@@ -62,14 +62,14 @@ f7 ()
{
T3 t = { 0, 0, 0, 0, 0, 0, 0 };
S s = __builtin_bit_cast (S, t);
- unsigned char c = s.c;
+ unsigned char c = s.c; // { dg-error "accessing uninitialized member" }
return true;
}
constexpr bool a = f1 ();
constexpr bool b = f2 ();
constexpr bool c = f3 ();
-constexpr bool d = f4 ();
-constexpr bool e = f5 (); // { dg-error "accessing uninitialized member" }
-constexpr bool f = f6 (); // { dg-error "accessing uninitialized member" }
-constexpr bool g = f7 (); // { dg-error "accessing uninitialized member" }
+constexpr bool d = f4 (); // { dg-message "in .constexpr. expansion" }
+constexpr bool e = f5 (); // { dg-message "in .constexpr. expansion" }
+constexpr bool f = f6 (); // { dg-message "in .constexpr. expansion" }
+constexpr bool g = f7 (); // { dg-message "in .constexpr. expansion" }
@@ -9,7 +9,7 @@ bar ()
{
V f { .b = 42 };
constexpr auto m = &V::a;
- return (f.*m) == 42;
+ return (f.*m) == 42; // { dg-error "accessing 'V::a' member instead of initialized 'V::b' member in constant expression" }
}
constexpr bool
@@ -21,5 +21,5 @@ baz ()
}
static_assert (bar (), ""); // { dg-error "non-constant condition for static assertion" }
- // { dg-error "accessing 'V::a' member instead of initialized 'V::b' member in constant expression" "" { target *-*-* } .-1 }
+ // { dg-message "in .constexpr. expansion" "" { target *-*-* } .-1 }
static_assert (baz (), "");
@@ -25,8 +25,7 @@ struct D : B, A {
constexpr B::B(V* v, A* a)
{
- dynamic_cast<B*>(a);
+ dynamic_cast<B*>(a); // { dg-error "accessing uninitialized member" }
}
-constexpr D d; // { dg-error "accessing uninitialized member" }
-// { dg-message "in 'constexpr' expansion of" "" { target *-*-* } .-1 }
+constexpr D d; // { dg-message "in 'constexpr' expansion of" }
@@ -52,11 +52,10 @@ constexpr int
fn5 ()
{
struct S { int a = 9; int b; } s;
- return s.b;
+ return s.b; // { dg-error "accessing uninitialized member" }
}
-constexpr int b = fn5 (); // { dg-error "accessing uninitialized member" }
-// { dg-message "in .constexpr. expansion of" "" { target *-*-* } .-1 }
+constexpr int b = fn5 (); // { dg-message "in .constexpr. expansion of" }
constexpr int
fn6 ()
@@ -17,11 +17,11 @@ struct B : A {
constexpr int
foo ()
{
- A *a = new B ();
+ A *a = new B (); // { dg-message "allocated here" }
a->a = 4;
delete a;
- int r = a->foo ();
+ int r = a->foo (); // { dg-error "constant expression" }
return r;
}
-constexpr auto a = foo (); // { dg-error "constant expression" }
+constexpr auto a = foo (); // { dg-message "in .constexpr. expansion" }
@@ -45,11 +45,10 @@ constexpr bool
f5 ()
{
int *p = new int; // { dg-message "allocated here" }
- return *p == 1;
+ return *p == 1; // { dg-error "the content of uninitialized storage is not usable in a constant expression" }
}
-constexpr auto v5 = f5 (); // { dg-error "the content of uninitialized storage is not usable in a constant expression" }
- // { dg-message "in 'constexpr' expansion of" "" { target *-*-* } .-1 }
+constexpr auto v5 = f5 (); // { dg-message "in 'constexpr' expansion of" }
constexpr bool
f6 ()
@@ -57,11 +56,10 @@ f6 ()
int *p = new int (2); // { dg-message "allocated here" }
int *q = p;
delete p;
- return *q == 2;
+ return *q == 2; // { dg-error "use of allocated storage after deallocation in a constant expression" }
}
-constexpr auto v6 = f6 (); // { dg-error "use of allocated storage after deallocation in a constant expression" }
- // { dg-message "in 'constexpr' expansion of" "" { target *-*-* } .-1 }
+constexpr auto v6 = f6 (); // { dg-message "in 'constexpr' expansion of" }
constexpr int *
f7 ()
@@ -11,15 +11,14 @@ struct S1
struct alignas(64) S2
{
constexpr S2 ()
- : m_tabS1()
+ : m_tabS1() // { dg-error "used before its definition" }
{}
S1 m_tabS1[7];
};
constinit S2 objX; // { dg-error ".constinit. variable .objX. does not have a constant initializer" }
-// { dg-error "used before its definition" "" { target *-*-* } .-1 }
-// // { dg-message "in .constexpr. expansion of" "" { target *-*-* } .-2 }
+// { dg-message "in .constexpr. expansion of" "" { target *-*-* } .-1 }
constexpr S1::S1 ()
: m_i(14)
@@ -14,8 +14,8 @@ is_corresponding_member (M1 S1::*m1, M2 S2::*m2) noexcept
struct A { int a; };
struct B;
constexpr int B::*n = nullptr;
-constexpr auto a = std::is_corresponding_member (&A::a, n); // { dg-error "invalid use of incomplete type 'struct B'" }
-constexpr auto b = std::is_corresponding_member (n, &A::a); // { dg-error "invalid use of incomplete type 'struct B'" }
+constexpr auto a = std::is_corresponding_member (&A::a, n); // { dg-message "in .constexpr. expansion of" }
+constexpr auto b = std::is_corresponding_member (n, &A::a); // { dg-message "in .constexpr. expansion of" }
void
foo (int B::*m)
@@ -4,7 +4,7 @@
constexpr int
fn_bad (int n)
{
- __extension__ int a [n] = { 0 };
+ __extension__ int a [n] = { 0 }; // { dg-error "array subscript" }
int z = a [0] + (n ? fn_bad (n - 1) : 0); // { dg-message "in .constexpr. expansion of " }
return z;
}
@@ -18,4 +18,4 @@ fn_ok (int n)
}
constexpr int i1 = fn_ok (3);
-constexpr int i2 = fn_bad (3); // { dg-error "array subscript|in .constexpr. expansion of " }
+constexpr int i2 = fn_bad (3); // { dg-message "in .constexpr. expansion of " }
@@ -4,11 +4,11 @@
constexpr int
foo (int n)
{
- __extension__ int a[n] = { 1, 2, 3, 4, 5, 6 };
+ __extension__ int a[n] = { 1, 2, 3, 4, 5, 6 }; // { dg-error "array subscript" }
int z = 0;
for (int i = 0; i <= n; ++i)
z += a[i];
return z;
}
-constexpr int n = foo (3); // { dg-error "array subscript|in .constexpr. expansion of " }
+constexpr int n = foo (3); // { dg-message "in .constexpr. expansion of " }
@@ -56,12 +56,13 @@ fn3 (int a, int b)
{
if (b != 2)
a = a / b; // { dg-error "..7 / 0.. is not a constant expression" }
+ // { dg-error "overflow in constant expression" "" { target *-*-* } .-1 }
return a;
}
constexpr int k1 = fn3 (8, 4);
constexpr int k2 = fn3 (7, 0); // { dg-message "in .constexpr. expansion" }
-constexpr int k3 = fn3 (INT_MIN, -1); // { dg-error "overflow in constant expression|in .constexpr. expansion of " }
+constexpr int k3 = fn3 (INT_MIN, -1); // { dg-message "in .constexpr. expansion of " }
SA (k1 == 2);
@@ -100,13 +101,13 @@ constexpr int
fn7 (const int *a, int b)
{
if (b != 3)
- return fn6 (*a, b);
+ return fn6 (*a, b); // { dg-error "null pointer" }
return 7;
}
constexpr int n1 = 7;
constexpr int n2 = fn7 (&n1, 5);
-constexpr int n3 = fn7 ((const int *) 0, 8); // { dg-error "null pointer|in .constexpr. expansion of " }
+constexpr int n3 = fn7 ((const int *) 0, 8); // { dg-message "in .constexpr. expansion of " }
constexpr int
fn8 (int i)
@@ -122,15 +123,15 @@ constexpr int
fn9 (int a, int b)
{
if (b != 0)
- return a + b;
+ return a + b; // { dg-error "overflow in constant expression" }
return a;
}
constexpr int p1 = fn9 (42, 7);
-constexpr int p2 = fn9 (__INT_MAX__, 1); // { dg-error "overflow in constant expression|in .constexpr. expansion of " }
+constexpr int p2 = fn9 (__INT_MAX__, 1); // { dg-message "in .constexpr. expansion of " }
constexpr int p3 = fn9 (__INT_MAX__, -1);
constexpr int p4 = fn9 (INT_MIN, 1);
-constexpr int p5 = fn9 (INT_MIN, -1); // { dg-error "overflow in constant expression|in .constexpr. expansion of " }
+constexpr int p5 = fn9 (INT_MIN, -1); // { dg-message "in .constexpr. expansion of " }
SA (p1 == 49);
SA (p3 == __INT_MAX__ - 1);
@@ -140,13 +141,13 @@ constexpr int
fn10 (int a, int b)
{
if (b != 0)
- return a * b;
+ return a * b; // { dg-error "overflow in constant expression" }
return a;
}
constexpr int q1 = fn10 (10, 10);
-constexpr int q2 = fn10 (__INT_MAX__, 2); // { dg-error "overflow in constant expression|in .constexpr. expansion of " }
-constexpr int q3 = fn10 (INT_MIN, 2); // { dg-error "overflow in constant expression|in .constexpr. expansion of " }
+constexpr int q2 = fn10 (__INT_MAX__, 2); // { dg-message "in .constexpr. expansion of " }
+constexpr int q3 = fn10 (INT_MIN, 2); // { dg-message "in .constexpr. expansion of " }
constexpr int q4 = fn10 (-1, -1);
SA (q1 == 100);
@@ -155,14 +156,14 @@ SA (q4 == 1);
constexpr int
fn11 (double d)
{
- int i = d;
+ int i = d; // { dg-error "overflow in constant expression" }
if (i != 0)
return i;
return i * 2;
}
constexpr int r1 = fn11 (3.4);
-constexpr int r2 = fn11 (__builtin_inf ()); // { dg-error "overflow in constant expression|in .constexpr. expansion of " }
+constexpr int r2 = fn11 (__builtin_inf ()); // { dg-message "in .constexpr. expansion of " }
constexpr int
fn12 (int i)
@@ -32,7 +32,7 @@ test01()
return outa;
}
-static_assert(test01()); // { dg-error "outside the bounds" }
+static_assert(test01()); // { dg-error "non-constant condition" }
constexpr bool
test02()
@@ -44,7 +44,8 @@ test02()
return outa;
}
-static_assert(test02()); // { dg-error "outside the bounds" }
+static_assert(test02()); // { dg-error "non-constant condition" }
-// { dg-prune-output "non-constant condition" }
+// Errors occuring within <algorithm> internals:
+// { dg-error "outside the bounds of array" "" { target *-*-* } 0 }
// { dg-prune-output "in 'constexpr'" }
@@ -13,9 +13,11 @@ static_assert( std::gcd(LLONG_MIN, 2ull) == 2 );
static_assert( std::gcd(2ull, LLONG_MIN) == 2 );
// But |INT_MIN| cannot be represented in common_type<int, int> i.e. int.
-constexpr int a = std::gcd(INT_MIN, 1); // { dg-error "overflow" }
-constexpr int b = std::gcd(1, INT_MIN); // { dg-error "overflow" }
+constexpr int a = std::gcd(INT_MIN, 1); // { dg-error "in .constexpr." }
+constexpr int b = std::gcd(1, INT_MIN); // { dg-error "in .constexpr." }
// And |LLONG_MIN| cannot be represented in long.
-constexpr long long c = std::gcd(LLONG_MIN, 1); // { dg-error "overflow" }
-constexpr long long d = std::gcd(1, LLONG_MIN); // { dg-error "overflow" }
+constexpr long long c = std::gcd(LLONG_MIN, 1); // { dg-error "in .constexpr." }
+constexpr long long d = std::gcd(1, LLONG_MIN); // { dg-error "in .constexpr." }
+
+// { dg-error "overflow" "" { target *-*-* } 0 }
@@ -9,14 +9,16 @@ static_assert( std::lcm(INT_MIN, 1u) == INT_MAX+1u );
static_assert( std::lcm(1u, INT_MIN) == INT_MAX+1u );
// But |INT_MIN| cannot be represented in common_type<int, int> i.e. int.
-constexpr int a = std::lcm(INT_MIN, 1); // { dg-error "overflow" }
-constexpr int b = std::lcm(1, INT_MIN); // { dg-error "overflow" }
+constexpr int a = std::lcm(INT_MIN, 1); // { dg-error "in .constexpr." }
+constexpr int b = std::lcm(1, INT_MIN); // { dg-error "in .constexpr." }
// And the LCM of 50000 and 49999 cannot be represented in int.
-constexpr int c = std::lcm(50000, 49999); // { dg-error "overflow" }
-constexpr int d = std::lcm(49999, 50000); // { dg-error "overflow" }
+constexpr int c = std::lcm(50000, 49999); // { dg-error "in .constexpr." }
+constexpr int d = std::lcm(49999, 50000); // { dg-error "in .constexpr." }
// Similarly for unsigned, but the diagnostic is a failed assertion instead.
-constexpr int e = std::lcm(500000u, 499999); // { dg-error "in 'constexpr'" }
-constexpr int f = std::lcm(499999u, 500000); // { dg-error "in 'constexpr'" }
+constexpr int e = std::lcm(500000u, 499999); // { dg-error "in .constexpr." }
+constexpr int f = std::lcm(499999u, 500000); // { dg-error "in .constexpr." }
+
+// { dg-error "overflow" "" { target *-*-* } 0 }
// { dg-error "unreachable" "" { target *-*-* } 0 }