On Fri, Jul 21, 2023 at 3:00 AM Jason Merrill <ja...@redhat.com> wrote: > > On 7/20/23 05:37, Nathaniel Shead wrote: > > This patch updates 'input_location' during constant evaluation to ensure > > that errors in subexpressions that lack location information still > > provide accurate diagnostics. > > > > By itself this change causes some small regressions in diagnostic > > quality for circumstances where errors used 'input_location' but the > > location of the parent subexpression doesn't make sense, so this patch > > also includes a couple of other small diagnostic improvements to improve > > the most egregious cases. > > > > gcc/cp/ChangeLog: > > > > * constexpr.cc (modifying_const_object_error): Find the source > > location of the const object's declaration. > > (cxx_eval_store_expression): Fall back to the location of the > > target object when evaluating initialiser. > > I'm skeptical about this workaround being an improvement in general. > Reverting it, there only seems to be a difference for constexpr-89285.C, > which seems fine; we see the location as the first line of the class, as > usual for implicitly declared constructors. > > Showing the DMI location might be an improvement, but I think it would > be better to make that change in perform_member_init so it applies to > runtime as well.
Makes sense, I'll get rid of it. > > (cxx_eval_constant_expression): Update input_location to the location > > of the currently evaluated expression, if possible. > > > > libstdc++-v3/ChangeLog: > > > > * testsuite/25_algorithms/equal/constexpr_neg.cc: Update diagnostic > > locations. > > * testsuite/26_numerics/gcd/105844.cc: Likewise. > > * testsuite/26_numerics/lcm/105844.cc: Likewise. > > > > gcc/testsuite/ChangeLog: > > > > * g++.dg/cpp0x/constexpr-48089.C: Update diagnostic locations. > > * g++.dg/cpp0x/constexpr-70323.C: Likewise. > > * g++.dg/cpp0x/constexpr-70323a.C: Likewise. > > * g++.dg/cpp0x/constexpr-delete2.C: Likewise. > > * g++.dg/cpp0x/constexpr-diag3.C: Likewise. > > * g++.dg/cpp0x/constexpr-ice20.C: Likewise. > > * g++.dg/cpp0x/constexpr-recursion.C: Likewise. > > * g++.dg/cpp0x/overflow1.C: Likewise. > > * g++.dg/cpp1y/constexpr-89285.C: Likewise. > > * g++.dg/cpp1y/constexpr-89481.C: Likewise. > > * g++.dg/cpp1y/constexpr-lifetime1.C: Likewise. > > * g++.dg/cpp1y/constexpr-lifetime2.C: Likewise. > > * g++.dg/cpp1y/constexpr-lifetime3.C: Likewise. > > * g++.dg/cpp1y/constexpr-lifetime4.C: Likewise. > > * g++.dg/cpp1y/constexpr-lifetime5.C: Likewise. > > * g++.dg/cpp1y/constexpr-tracking-const14.C: Likewise. > > * g++.dg/cpp1y/constexpr-tracking-const16.C: Likewise. > > * g++.dg/cpp1y/constexpr-tracking-const18.C: Likewise. > > * g++.dg/cpp1y/constexpr-tracking-const19.C: Likewise. > > * g++.dg/cpp1y/constexpr-tracking-const21.C: Likewise. > > * g++.dg/cpp1y/constexpr-tracking-const22.C: Likewise. > > * g++.dg/cpp1y/constexpr-tracking-const3.C: Likewise. > > * g++.dg/cpp1y/constexpr-tracking-const4.C: Likewise. > > * g++.dg/cpp1y/constexpr-tracking-const7.C: Likewise. > > * g++.dg/cpp1y/constexpr-union5.C: Likewise. > > * g++.dg/cpp1y/pr68180.C: Likewise. > > * g++.dg/cpp1z/constexpr-lambda6.C: Likewise. > > * g++.dg/cpp1z/constexpr-lambda8.C: Likewise. > > * g++.dg/cpp2a/bit-cast11.C: Likewise. > > * g++.dg/cpp2a/bit-cast12.C: Likewise. > > * g++.dg/cpp2a/bit-cast14.C: Likewise. > > * g++.dg/cpp2a/constexpr-98122.C: Likewise. > > * g++.dg/cpp2a/constexpr-dynamic17.C: Likewise. > > * g++.dg/cpp2a/constexpr-init1.C: Likewise. > > * g++.dg/cpp2a/constexpr-new12.C: Likewise. > > * g++.dg/cpp2a/constexpr-new3.C: Likewise. > > * g++.dg/cpp2a/constinit10.C: Likewise. > > * g++.dg/cpp2a/is-corresponding-member4.C: Likewise. > > * g++.dg/ext/constexpr-vla2.C: Likewise. > > * g++.dg/ext/constexpr-vla3.C: Likewise. > > * g++.dg/ubsan/pr63956.C: Likewise. > > > > Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> > > --- > > gcc/cp/constexpr.cc | 46 ++++++++++++++++++- > > gcc/testsuite/g++.dg/cpp0x/constexpr-48089.C | 10 ++-- > > gcc/testsuite/g++.dg/cpp0x/constexpr-70323.C | 8 ++-- > > gcc/testsuite/g++.dg/cpp0x/constexpr-70323a.C | 8 ++-- > > .../g++.dg/cpp0x/constexpr-delete2.C | 5 +- > > gcc/testsuite/g++.dg/cpp0x/constexpr-diag3.C | 2 +- > > gcc/testsuite/g++.dg/cpp0x/constexpr-ice20.C | 1 + > > .../g++.dg/cpp0x/constexpr-recursion.C | 6 +-- > > gcc/testsuite/g++.dg/cpp0x/overflow1.C | 2 +- > > gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C | 5 +- > > gcc/testsuite/g++.dg/cpp1y/constexpr-89481.C | 3 +- > > .../g++.dg/cpp1y/constexpr-lifetime1.C | 1 + > > .../g++.dg/cpp1y/constexpr-lifetime2.C | 4 +- > > .../g++.dg/cpp1y/constexpr-lifetime3.C | 4 +- > > .../g++.dg/cpp1y/constexpr-lifetime4.C | 2 +- > > .../g++.dg/cpp1y/constexpr-lifetime5.C | 4 +- > > .../g++.dg/cpp1y/constexpr-tracking-const14.C | 3 +- > > .../g++.dg/cpp1y/constexpr-tracking-const16.C | 3 +- > > .../g++.dg/cpp1y/constexpr-tracking-const18.C | 4 +- > > .../g++.dg/cpp1y/constexpr-tracking-const19.C | 4 +- > > .../g++.dg/cpp1y/constexpr-tracking-const21.C | 4 +- > > .../g++.dg/cpp1y/constexpr-tracking-const22.C | 4 +- > > .../g++.dg/cpp1y/constexpr-tracking-const3.C | 3 +- > > .../g++.dg/cpp1y/constexpr-tracking-const4.C | 3 +- > > .../g++.dg/cpp1y/constexpr-tracking-const7.C | 3 +- > > gcc/testsuite/g++.dg/cpp1y/constexpr-union5.C | 4 +- > > gcc/testsuite/g++.dg/cpp1y/pr68180.C | 4 +- > > .../g++.dg/cpp1z/constexpr-lambda6.C | 4 +- > > .../g++.dg/cpp1z/constexpr-lambda8.C | 5 +- > > gcc/testsuite/g++.dg/cpp2a/bit-cast11.C | 10 ++-- > > gcc/testsuite/g++.dg/cpp2a/bit-cast12.C | 10 ++-- > > gcc/testsuite/g++.dg/cpp2a/bit-cast14.C | 14 +++--- > > gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C | 4 +- > > .../g++.dg/cpp2a/constexpr-dynamic17.C | 5 +- > > gcc/testsuite/g++.dg/cpp2a/constexpr-init1.C | 5 +- > > gcc/testsuite/g++.dg/cpp2a/constexpr-new12.C | 6 +-- > > gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C | 10 ++-- > > gcc/testsuite/g++.dg/cpp2a/constinit10.C | 5 +- > > .../g++.dg/cpp2a/is-corresponding-member4.C | 4 +- > > gcc/testsuite/g++.dg/ext/constexpr-vla2.C | 4 +- > > gcc/testsuite/g++.dg/ext/constexpr-vla3.C | 4 +- > > gcc/testsuite/g++.dg/ubsan/pr63956.C | 23 +++++----- > > .../25_algorithms/equal/constexpr_neg.cc | 7 +-- > > .../testsuite/26_numerics/gcd/105844.cc | 10 ++-- > > .../testsuite/26_numerics/lcm/105844.cc | 14 +++--- > > 45 files changed, 170 insertions(+), 124 deletions(-) > > > > diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc > > index cd4424bcb44..63e8274e0dc 100644 > > --- a/gcc/cp/constexpr.cc > > +++ b/gcc/cp/constexpr.cc > > @@ -2178,7 +2178,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 > > @@ -6276,6 +6302,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 > > @@ -6964,7 +7005,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-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 <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 <> > > diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C > > b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C > > index fe0b8570ca2..d09df091fdb 100644 > > --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C > > +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-89285.C > > @@ -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 } } > > 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-lifetime1.C > > b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C > > index 43aa7c974c1..f79f1611d5f 100644 > > --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C > > +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime1.C > > @@ -11,3 +11,4 @@ constexpr const int& test() { > > return local.get(); > > } > > constexpr int x = test(); // { dg-error "accessing object outside its > > lifetime" } > > + > > diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C > > b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C > > index 22cd919fcda..2f5ae8db6d5 100644 > > --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C > > +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime2.C > > @@ -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 > > diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C > > b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C > > index 6329f8cf6c6..53785521d05 100644 > > --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C > > +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime3.C > > @@ -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" } > > diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C > > b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C > > index 181a1201663..4302da1eddc 100644 > > --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C > > +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime4.C > > @@ -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), ""); > > diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C > > b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C > > index ad3ef579f63..a12920c8fba 100644 > > --- a/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C > > +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-lifetime5.C > > @@ -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" } > > 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 &>(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 <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 }; > > 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 <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 }; > > 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 <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 }; > > 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 <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 }; > > 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 &>(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<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; > > } > > diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda6.C > > b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda6.C > > index 214d3821299..c46c2d4c7fe 100644 > > --- a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda6.C > > +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda6.C > > @@ -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 > > diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda8.C > > b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda8.C > > index 84be68ab7f0..82351ff0c54 100644 > > --- a/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda8.C > > +++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-lambda8.C > > @@ -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 > > diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast11.C > > b/gcc/testsuite/g++.dg/cpp2a/bit-cast11.C > > index a3eb31bc6c7..760c9ca40b4 100644 > > --- a/gcc/testsuite/g++.dg/cpp2a/bit-cast11.C > > +++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast11.C > > @@ -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" } > > diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast12.C > > b/gcc/testsuite/g++.dg/cpp2a/bit-cast12.C > > index 9c699dd55f0..e205bc6a8c1 100644 > > --- a/gcc/testsuite/g++.dg/cpp2a/bit-cast12.C > > +++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast12.C > > @@ -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" } > > diff --git a/gcc/testsuite/g++.dg/cpp2a/bit-cast14.C > > b/gcc/testsuite/g++.dg/cpp2a/bit-cast14.C > > index 5e185919be4..e0cc9a39702 100644 > > --- a/gcc/testsuite/g++.dg/cpp2a/bit-cast14.C > > +++ b/gcc/testsuite/g++.dg/cpp2a/bit-cast14.C > > @@ -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" } > > diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C > > b/gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C > > index 01bdfa5bd4d..b0c91d5ef97 100644 > > --- a/gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C > > +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-98122.C > > @@ -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 (), ""); > > diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic17.C > > b/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic17.C > > index a26678e6ed7..28facf192df 100644 > > --- a/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic17.C > > +++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dynamic17.C > > @@ -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" } > > 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 <algorithm> 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<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 } > > 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<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 } >