diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 5e0fe93ebc0..03a49c59933 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -2160,7 +2160,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 % 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 % here"); } /* Return true if FNDECL is a replaceable global allocation function that @@ -6959,7 +6985,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); diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C index 4574eb83ff7..11630f26ffe 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C @@ -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 { diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-70323.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-70323.C index 272a225d967..bfb185f2fb5 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-70323.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-70323.C @@ -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 " } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-70323a.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-70323a.C index 1990ab6be2d..b5ed581e1c8 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-70323a.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-70323a.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-delete2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-delete2.C index 999f9b7851e..f2b6df2509c 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-delete2.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-delete2.C @@ -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 } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C index 5eedf42ba36..50c676c56cd 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C @@ -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: diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C index e2d4853a284..43fa9a03c14 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C index 51499fac520..bdb2677a350 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-mutable3.C @@ -4,6 +4,7 @@ struct A { mutable int m; }; constexpr int f(A a) { return a.m; } +// { dg-error "mutable" "" { target c++11_only } .-1 } static_assert(f({42}) == 42, ""); -// { dg-error "non-constant|mutable" "" { target c++11_only } .-1 } +// { dg-error "non-constant" "" { target c++11_only } .-1 } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion.C index 8c4201e1ec2..b00f8794d4c 100644 --- a/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion.C +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-recursion.C @@ -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); diff --git a/gcc/testsuite/g++.dg/cpp0x/overflow1.C b/gcc/testsuite/g++.dg/cpp0x/overflow1.C index b8591b4af41..e295355c88f 100644 --- a/gcc/testsuite/g++.dg/cpp0x/overflow1.C +++ b/gcc/testsuite/g++.dg/cpp0x/overflow1.C @@ -4,7 +4,7 @@ template struct Fib { static const long long value // { dg-error "overflow" } - = Fib::value + Fib::value; + = Fib::value + Fib::value; // { dg-error "overflow" } }; template <> diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C index fe0b8570ca2..efbf9bd15dd 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C @@ -13,8 +13,9 @@ struct B { *c = reinterpret_cast(this) - reinterpret_cast(c); // { dg-error "reinterpret_cast" "" { target c++20_down } } } }; -struct C : A { +struct C : A { // { dg-error "" "" { target c++14_down } } B bar {this}; }; -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 } } diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C index 8ac4ef0fd36..6f8f6a8038e 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C @@ -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 } diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const14.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const14.C index 45c4fcf50be..0c77dd4934d 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const14.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const14.C @@ -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).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" } diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const16.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const16.C index 5a5b92bc8cc..b5ccf3a4ea5 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const16.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const16.C @@ -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 } diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const18.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const18.C index 11a680468c2..278628c121b 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const18.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const18.C @@ -13,11 +13,11 @@ struct array template struct S { using U = array; - const U m; + const U m; // { dg-message "originally declared" } constexpr S(int) : m{} { const_cast(const_cast(m)[0]) = 42; // { dg-error "modifying a const object" } } }; -constexpr S p = { 10 }; // { dg-message "originally declared" } +constexpr S p = { 10 }; diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const19.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const19.C index c31222ffcdd..2d18c94537b 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const19.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const19.C @@ -7,7 +7,7 @@ template 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 @@ -20,4 +20,4 @@ struct S { } }; -constexpr S p = { 10 }; // { dg-message "originally declared" } +constexpr S p = { 10 }; diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const21.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const21.C index 0b16193398e..d3bbcb116a6 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const21.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const21.C @@ -18,11 +18,11 @@ struct array2 { template struct S { using U = array2; - const U m; + const U m; // { dg-message "originally declared" } constexpr S(int) : m{} { const_cast(m.a[0]) = 42; // { dg-error "modifying a const object" } } }; -constexpr S p = { 10 }; // { dg-message "originally declared" } +constexpr S p = { 10 }; diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const22.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const22.C index 216cf1607a4..27522f86dbd 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const22.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const22.C @@ -7,11 +7,11 @@ struct X { template struct S { - const X x; + const X x; // { dg-message "originally declared" } constexpr S(int) : x{} { const_cast(x).i = 19; // { dg-error "modifying a const object" } } }; -constexpr S p = { 10 }; // { dg-message "originally declared" } +constexpr S p = { 10 }; diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const3.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const3.C index 6853775c1e2..fc88dd05eef 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const3.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const3.C @@ -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).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), ""); diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const4.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const4.C index 8263a7cc505..27fede152c7 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const4.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const4.C @@ -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), ""); diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const7.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const7.C index 922e8ff126f..bea14b05602 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const7.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const7.C @@ -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), ""); diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C index 55fe9fa2f0b..3d76345d564 100644 --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/cpp1y/pr68180.C b/gcc/testsuite/g++.dg/cpp1y/pr68180.C index 9e6e5e984f9..8de1ef3936b 100644 --- a/gcc/testsuite/g++.dg/cpp1y/pr68180.C +++ b/gcc/testsuite/g++.dg/cpp1y/pr68180.C @@ -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(a); + dynamic_cast(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" } diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C index e56ecfed48a..b4e39b6f928 100644 --- a/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C @@ -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 () diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C index 5a3d06a5fab..832782e1427 100644 --- a/gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C @@ -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" } diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C b/gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C index 70b841208f8..3ba440fec53 100644 --- a/gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C @@ -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 () diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit10.C b/gcc/testsuite/g++.dg/cpp2a/constinit10.C index b678788541e..d2c49c41f91 100644 --- a/gcc/testsuite/g++.dg/cpp2a/constinit10.C +++ b/gcc/testsuite/g++.dg/cpp2a/constinit10.C @@ -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) diff --git a/gcc/testsuite/g++.dg/cpp2a/is-corresponding-member4.C b/gcc/testsuite/g++.dg/cpp2a/is-corresponding-member4.C index 6b74090306b..241e9976e8c 100644 --- a/gcc/testsuite/g++.dg/cpp2a/is-corresponding-member4.C +++ b/gcc/testsuite/g++.dg/cpp2a/is-corresponding-member4.C @@ -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) diff --git a/gcc/testsuite/g++.dg/ext/constexpr-vla2.C b/gcc/testsuite/g++.dg/ext/constexpr-vla2.C index d4ea7c58c0d..e09a27af3de 100644 --- a/gcc/testsuite/g++.dg/ext/constexpr-vla2.C +++ b/gcc/testsuite/g++.dg/ext/constexpr-vla2.C @@ -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 " } diff --git a/gcc/testsuite/g++.dg/ext/constexpr-vla3.C b/gcc/testsuite/g++.dg/ext/constexpr-vla3.C index 538b576a825..6f9daa1897f 100644 --- a/gcc/testsuite/g++.dg/ext/constexpr-vla3.C +++ b/gcc/testsuite/g++.dg/ext/constexpr-vla3.C @@ -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 " } diff --git a/gcc/testsuite/g++.dg/ubsan/pr63956.C b/gcc/testsuite/g++.dg/ubsan/pr63956.C index 3a1596e6e2e..6fd0b4f893e 100644 --- a/gcc/testsuite/g++.dg/ubsan/pr63956.C +++ b/gcc/testsuite/g++.dg/ubsan/pr63956.C @@ -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) diff --git a/libstdc++-v3/testsuite/25_algorithms/equal/constexpr_neg.cc b/libstdc++-v3/testsuite/25_algorithms/equal/constexpr_neg.cc index 34ca5c4805c..fd89ac0e166 100644 --- a/libstdc++-v3/testsuite/25_algorithms/equal/constexpr_neg.cc +++ b/libstdc++-v3/testsuite/25_algorithms/equal/constexpr_neg.cc @@ -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 internals: +// { dg-error "outside the bounds of array" "" { target *-*-* } 0 } // { dg-prune-output "in 'constexpr'" } diff --git a/libstdc++-v3/testsuite/26_numerics/gcd/105844.cc b/libstdc++-v3/testsuite/26_numerics/gcd/105844.cc index 5b6fea7b560..bc9b29bc39d 100644 --- a/libstdc++-v3/testsuite/26_numerics/gcd/105844.cc +++ b/libstdc++-v3/testsuite/26_numerics/gcd/105844.cc @@ -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 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 } diff --git a/libstdc++-v3/testsuite/26_numerics/lcm/105844.cc b/libstdc++-v3/testsuite/26_numerics/lcm/105844.cc index d0e032e03e0..d853974f77e 100644 --- a/libstdc++-v3/testsuite/26_numerics/lcm/105844.cc +++ b/libstdc++-v3/testsuite/26_numerics/lcm/105844.cc @@ -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 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 }