Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

Presenting the allocation location as the location of the outermost
expression we're trying to evaluate is inaccurate; let's provide both
locations.

gcc/cp/ChangeLog:

        * constexpr.cc (cxx_eval_outermost_constant_expr): Give both
        expression and allocation location in allocated storage diagnostics.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp1y/constexpr-new.C: Adjust diagnostics.
        * g++.dg/cpp1z/constexpr-asm-5.C: Likewise.
        * g++.dg/cpp26/static_assert1.C: Likewise.
        * g++.dg/cpp2a/constexpr-dtor7.C: Likewise.
        * g++.dg/cpp2a/constexpr-new26.C: Likewise.
        * g++.dg/cpp2a/constexpr-new3.C: Likewise.
        * g++.dg/cpp2a/constinit14.C: Likewise.
---
 gcc/cp/constexpr.cc                          | 16 ++++++++++------
 gcc/testsuite/g++.dg/cpp1y/constexpr-new.C   |  6 ++++--
 gcc/testsuite/g++.dg/cpp1z/constexpr-asm-5.C |  4 +++-
 gcc/testsuite/g++.dg/cpp26/static_assert1.C  |  3 ++-
 gcc/testsuite/g++.dg/cpp2a/constexpr-dtor7.C |  3 ++-
 gcc/testsuite/g++.dg/cpp2a/constexpr-new26.C |  5 ++---
 gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C  | 12 ++++++------
 gcc/testsuite/g++.dg/cpp2a/constinit14.C     |  3 ++-
 8 files changed, 31 insertions(+), 21 deletions(-)

diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc
index d647a09269d..8a5b68c71fa 100644
--- a/gcc/cp/constexpr.cc
+++ b/gcc/cp/constexpr.cc
@@ -9262,9 +9262,11 @@ cxx_eval_outermost_constant_expr (tree t, bool 
allow_non_constant,
       if (heap_var)
        {
          if (!allow_non_constant && !non_constant_p)
-           error_at (DECL_SOURCE_LOCATION (heap_var),
-                     "%qE is not a constant expression because it refers to "
-                     "a result of %<operator new%>", t);
+           {
+             error ("%qE is not a constant expression because it refers to "
+                    "a result of %<operator new%>", t);
+             inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
+           }
          r = t;
          non_constant_p = true;
        }
@@ -9273,9 +9275,11 @@ cxx_eval_outermost_constant_expr (tree t, bool 
allow_non_constant,
          if (DECL_NAME (heap_var) != heap_deleted_identifier)
            {
              if (!allow_non_constant && !non_constant_p)
-               error_at (DECL_SOURCE_LOCATION (heap_var),
-                         "%qE is not a constant expression because allocated "
-                         "storage has not been deallocated", t);
+               {
+                 error ("%qE is not a constant expression because allocated "
+                        "storage has not been deallocated", t);
+                 inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
+               }
              r = t;
              non_constant_p = true;
            }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-new.C 
b/gcc/testsuite/g++.dg/cpp1y/constexpr-new.C
index d0ca0b7d27f..f4c6d2e534d 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-new.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-new.C
@@ -6,7 +6,9 @@ constexpr int *f4(bool b) {
     return nullptr;
   } else {
     return new int{42}; // { dg-error "call to non-.constexpr." "" { target 
c++17_down } }
-  }                    // { dg-error "is not a constant expression because 
allocated storage has not been deallocated" "" { target c++2a } .-1 }
+    // { dg-message "allocated here" "" { target c++20 } .-1 }
+  }
 }
 static_assert(f4(true) == nullptr, "");
-static_assert(f4(false) == nullptr, ""); // { dg-error "non-.constant. 
condition|" }
+static_assert(f4(false) == nullptr, ""); // { dg-error "non-constant 
condition" }
+// { dg-error "is not a constant expression because allocated storage has not 
been deallocated" "" { target c++20 } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-asm-5.C 
b/gcc/testsuite/g++.dg/cpp1z/constexpr-asm-5.C
index bcecea9d6b5..35beb27f7d5 100644
--- a/gcc/testsuite/g++.dg/cpp1z/constexpr-asm-5.C
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-asm-5.C
@@ -28,7 +28,7 @@ struct M { constexpr K size () const { return {}; }
           constexpr L data () const { return {}; } };
 #if  __cpp_constexpr_dynamic_alloc >= 201907L
 struct N { constexpr int size () const { return 3; }
-          constexpr const char *data () const { return new char[3] { 'b', 'a', 
'd' }; } }; // { dg-error "'\\\* N\\\(\\\).N::data\\\(\\\)' is not a constant 
expression because allocated storage has not been deallocated" "" { target 
c++20 } }
+          constexpr const char *data () const { return new char[3] { 'b', 'a', 
'd' }; } };
 #endif
 constexpr const char a[] = { 't', 'e', 's', 't' };
 struct O { constexpr int size () const { return 4; }
@@ -117,6 +117,7 @@ foo ()
   asm ((M {}));
 #if __cpp_constexpr_dynamic_alloc >= 201907L
   asm ((N {}));                        // { dg-error "constexpr string 
'data\\\(\\\)\\\[0\\\]' must be a constant expression" "" { target c++20 } }
+ // { dg-error "'\\\* N\\\(\\\).N::data\\\(\\\)' is not a constant expression 
because allocated storage has not been deallocated" "" { target c++20 } .-1 }
 #endif
   asm ((O {}));
   asm ((P (0)));
@@ -190,6 +191,7 @@ bar ()
   asm ((M {}));
 #if __cpp_constexpr_dynamic_alloc >= 201907L
   asm ((N {}));                        // { dg-error "constexpr string 
'data\\\(\\\)\\\[0\\\]' must be a constant expression" "" { target c++20 } }
+ // { dg-error "'\\\* N\\\(\\\).N::data\\\(\\\)' is not a constant expression 
because allocated storage has not been deallocated" "" { target c++20 } .-1 }
 #endif
   asm ((O {}));
   asm ((P (0)));
diff --git a/gcc/testsuite/g++.dg/cpp26/static_assert1.C 
b/gcc/testsuite/g++.dg/cpp26/static_assert1.C
index f9ac8311b82..1d0e6f2840f 100644
--- a/gcc/testsuite/g++.dg/cpp26/static_assert1.C
+++ b/gcc/testsuite/g++.dg/cpp26/static_assert1.C
@@ -69,10 +69,11 @@ static_assert (false, M {});        // { dg-warning 
"'static_assert' with non-string me
                                // { dg-error "static assertion failed: test" 
"" { target *-*-* } .-1 }
 #if  __cpp_constexpr_dynamic_alloc >= 201907L
 struct N { constexpr int size () const { return 3; }
-          constexpr const char *data () const { return new char[3] { 'b', 'a', 
'd' }; } }; // { dg-error "'\\\* N\\\(\\\).N::data\\\(\\\)' is not a constant 
expression because allocated storage has not been deallocated" "" { target 
c++20 } }
+          constexpr const char *data () const { return new char[3] { 'b', 'a', 
'd' }; } };
 static_assert (true, N {});    // { dg-warning "'static_assert' with 
non-string message only available with" "" { target { c++20 && c++23_down } } }
 static_assert (false, N {});   // { dg-warning "'static_assert' with 
non-string message only available with" "" { target { c++20 && c++23_down } } }
                                // { dg-error "constexpr string 
'data\\\(\\\)\\\[0\\\]' must be a constant expression" "" { target c++20 } .-1 }
+                               // { dg-error "'\\\* N\\\(\\\).N::data\\\(\\\)' 
is not a constant expression because allocated storage has not been 
deallocated" "" { target c++20 } .-2 }
 #endif
 constexpr const char a[] = { 't', 'e', 's', 't' };
 struct O { constexpr int size () const { return 4; }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor7.C 
b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor7.C
index 463eaca0539..f4546c18cc2 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor7.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-dtor7.C
@@ -3,7 +3,7 @@
 
 struct S {
   int *s;
-  constexpr S () : s(new int) {}       // { dg-error "is not a constant 
expression because allocated storage has not been deallocated" }
+  constexpr S () : s(new int) {}
   S (const S &) = delete;
   S &operator= (const S &) = delete;
   constexpr ~S () { delete s; }
@@ -17,3 +17,4 @@ foo (S v)
 }
 
 static_assert (foo (S ()));    // { dg-error "non-constant condition for 
static assertion" }
+// { dg-error "is not a constant expression because allocated storage has not 
been deallocated" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new26.C 
b/gcc/testsuite/g++.dg/cpp2a/constexpr-new26.C
index c82bd43205f..d8e53b25b9d 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-new26.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new26.C
@@ -4,7 +4,7 @@
 constexpr int *
 f7 ()
 {
-  int *p = new int (2);        // { dg-error "is not a constant expression 
because it refers to a result of" }
+  int *p = new int (2);                // { dg-message "allocated here" }
   delete p;
   return p;
 }
@@ -12,6 +12,5 @@ f7 ()
 void
 g ()
 {
-  constexpr auto v7 = f7 ();
+  constexpr auto v7 = f7 (); // { dg-error "is not a constant expression 
because it refers to a result of" }
 }
-
diff --git a/gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C 
b/gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C
index 5d9f192507b..30e453eaa34 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C
@@ -5,19 +5,19 @@
 constexpr int *
 f1 ()
 {
-  return new int (2);          // { dg-error "is not a constant expression 
because it refers to a result of" }
+  return new int (2);          // { dg-message "allocated here" }
 }
 
-constexpr auto v1 = f1 ();
+constexpr auto v1 = f1 (); // { dg-error "is not a constant expression because 
it refers to a result of" }
 
 constexpr bool
 f2 ()
 {
-  int *p = new int (3);                // { dg-error "is not a constant 
expression because allocated storage has not been deallocated" }
+  int *p = new int (3);                // { dg-message "allocated here" }
   return false;
 }
 
-constexpr auto v2 = f2 ();
+constexpr auto v2 = f2 (); // { dg-error "is not a constant expression because 
allocated storage has not been deallocated" }
 
 constexpr bool
 f3 ()
@@ -64,12 +64,12 @@ constexpr auto v6 = f6 ();  // { dg-message "in 'constexpr' 
expansion of" }
 constexpr int *
 f7 ()
 {
-  int *p = new int (2);                // { dg-error "is not a constant 
expression because it refers to a result of" }
+  int *p = new int (2);                // { dg-message "allocated here" }
   delete p;
   return p;
 }
 
-constexpr auto v7 = f7 ();
+constexpr auto v7 = f7 (); // { dg-error "is not a constant expression because 
it refers to a result of" }
 
 constexpr bool
 f8_impl (int *p)
diff --git a/gcc/testsuite/g++.dg/cpp2a/constinit14.C 
b/gcc/testsuite/g++.dg/cpp2a/constinit14.C
index 06c4cb46722..26d82fe673e 100644
--- a/gcc/testsuite/g++.dg/cpp2a/constinit14.C
+++ b/gcc/testsuite/g++.dg/cpp2a/constinit14.C
@@ -2,12 +2,13 @@
 // { dg-do compile { target c++20 } }
 
 struct Value {
-  Value() : v{new int{42}} {}  // { dg-error "result of 'operator new'" "" { 
target implicit_constexpr } }
+  Value() : v{new int{42}} {}
   int* v;
 };
 
 struct S {
   static constinit inline Value v{}; // { dg-error "variable .S::v. does not 
have a constant initializer|call to non-.constexpr. function" }
+  // { dg-error "result of 'operator new'" "" { target implicit_constexpr } 
.-1 }
 };
 
 int main() { return *S::v.v; }

base-commit: 53d4e355db18fec21515d055924df8290ef5ce14
-- 
2.49.0

Reply via email to