]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: constexpr new diagnostic location
authorJason Merrill <jason@redhat.com>
Mon, 10 Mar 2025 15:49:57 +0000 (11:49 -0400)
committerJason Merrill <jason@redhat.com>
Thu, 17 Apr 2025 17:21:09 +0000 (13:21 -0400)
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
gcc/testsuite/g++.dg/cpp1y/constexpr-new.C
gcc/testsuite/g++.dg/cpp1z/constexpr-asm-5.C
gcc/testsuite/g++.dg/cpp26/static_assert1.C
gcc/testsuite/g++.dg/cpp2a/constexpr-dtor7.C
gcc/testsuite/g++.dg/cpp2a/constexpr-new26.C
gcc/testsuite/g++.dg/cpp2a/constexpr-new3.C
gcc/testsuite/g++.dg/cpp2a/constinit14.C

index d647a09269d3a6506832a6a7a2c14b69ac74c8e1..8a5b68c71fafa7a24bb0fe7f739f6b46d81a47ec 100644 (file)
@@ -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;
            }
index d0ca0b7d27f7998e780a41d49b69641bda22f4f1..f4c6d2e534d92fe2e3c621dab47e4f1200ecfb9e 100644 (file)
@@ -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 }
index bcecea9d6b505cf88582ef7983937c352be336ee..35beb27f7d5306d7489291724308ee52a9a60303 100644 (file)
@@ -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)));
index f9ac8311b82760dfa3c8d13d5a7c27e613fb5349..1d0e6f2840f12ffc502dc6ffe29240025a7d8e79 100644 (file)
@@ -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; }
index 463eaca05394409761b853565195f0358e55eb44..f4546c18cc239529382f492ae45543826538b005 100644 (file)
@@ -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 }
index c82bd43205f45d157c3794ff99b96f0f75e49a68..d8e53b25b9db0be449f6443b179e90c15c3c79f4 100644 (file)
@@ -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" }
 }
-
index 5d9f192507b8d95c1a88c5cfba52148f47534617..30e453eaa34fb1e486c845fcc60448a1ca873e01 100644 (file)
@@ -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)
index 06c4cb46722f6f4049fd7a9e0aafaac7a6f462a6..26d82fe673e4150faa26914382639e25f7b0c4c9 100644 (file)
@@ -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; }