public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Nathaniel Shead <nathanieloshead@gmail.com>
To: Jason Merrill <jason@redhat.com>
Cc: gcc-patches@gcc.gnu.org, Patrick Palka <ppalka@redhat.com>
Subject: Re: [PATCH v4 3/3] c++: Improve location information in constant evaluation
Date: Sat, 22 Jul 2023 15:26:53 +1000	[thread overview]
Message-ID: <CACEF2k6A4GUnpWaVK2A6m3N6eUtVpU+4QatdmZOWaou-pXsR1Q@mail.gmail.com> (raw)
In-Reply-To: <ca734fe1-bcaf-c099-10f5-8286b42af672@redhat.com>

On Fri, Jul 21, 2023 at 3:00 AM Jason Merrill <jason@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 <nathanieloshead@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 }
>

      reply	other threads:[~2023-07-22  5:27 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-20  9:33 [PATCH v4 0/3] c++: Track lifetimes in constant evaluation [PR70331, ...] Nathaniel Shead
2023-07-20  9:35 ` [PATCH v4 1/3] c++: Track lifetimes in constant evaluation [PR70331,PR96630,PR98675] Nathaniel Shead
2023-07-20 14:42   ` Jason Merrill
2023-07-22  5:28     ` Nathaniel Shead
2023-07-20  9:36 ` [PATCH v4 2/3] c++: Improve constexpr error for dangling local variables [PR110619] Nathaniel Shead
2023-07-20 15:46   ` Jason Merrill
2023-07-21  5:39     ` Nathaniel Shead
2023-07-21 21:44       ` Jason Merrill
2023-07-22  5:20         ` Nathaniel Shead
2023-07-20  9:37 ` [PATCH v4 3/3] c++: Improve location information in constant evaluation Nathaniel Shead
2023-07-20 17:00   ` Jason Merrill
2023-07-22  5:26     ` Nathaniel Shead [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CACEF2k6A4GUnpWaVK2A6m3N6eUtVpU+4QatdmZOWaou-pXsR1Q@mail.gmail.com \
    --to=nathanieloshead@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    --cc=ppalka@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).