diff options
author | Nathaniel Shead <nathanieloshead@gmail.com> | 2023-07-23 01:13:43 +1000 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2023-07-25 21:45:10 -0400 |
commit | 5ebe5bcf8b6b6a0de16737b717e8bd06e4950a14 (patch) | |
tree | 6729835611be593167053724c99df1544bf496d6 /gcc | |
parent | 2ace6cd69429e0078147cdeaa16b92fab0002a02 (diff) | |
download | gcc-5ebe5bcf8b6b6a0de16737b717e8bd06e4950a14.zip gcc-5ebe5bcf8b6b6a0de16737b717e8bd06e4950a14.tar.gz gcc-5ebe5bcf8b6b6a0de16737b717e8bd06e4950a14.tar.bz2 |
c++: Improve location information in constant evaluation
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 small diagnostic improvement to fix the most egregious
case.
gcc/cp/ChangeLog:
* constexpr.cc (modifying_const_object_error): Find the source
location of the const object's declaration.
(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-mutable3.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-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 <nathanieloshead@gmail.com>
Diffstat (limited to 'gcc')
38 files changed, 131 insertions, 105 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 5e0fe93..03a49c5 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 %<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 @@ -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 4574eb8..11630f2 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 272a225..bfb185f 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 1990ab6..b5ed581 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 999f9b7..f2b6df2 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 5eedf42..50c676c 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 e2d4853..43fa9a0 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 51499fa..bdb2677 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 8c4201e..b00f879 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 b8591b4..e295355 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 fe0b857..efbf9bd 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<char *>(this) - reinterpret_cast<char *>(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 8ac4ef0..6f8f6a8 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 45c4fcf..0c77dd4 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 5a5b92b..b5ccf3a 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 11a6804..278628c 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 c31222f..2d18c94 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 0b16193..d3bbcb1 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 216cf16..27522f8 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 6853775..fc88dd0 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 8263a7c..27fede1 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 922e8ff..bea14b0 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 55fe9fa..3d76345 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 9e6e5e9..8de1ef3 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 214d382..c46c2d4 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 84be68a..82351ff 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 a3eb31b..760c9ca 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 9c699dd..e205bc6a 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 5e18591..e0cc9a3 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 01bdfa5..b0c91d5 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 a26678e..28facf1 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 e56ecfe..b4e39b6 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 5a3d06a..832782e 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 70b8412..3ba440f 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 b678788..d2c49c4 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 6b74090..241e997 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 d4ea7c5..e09a27a 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 538b576..6f9daa1 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 3a1596e..6fd0b4f 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) |