c++: constexpr new diagnostic location
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.
This commit is contained in:
parent
53d4e355db
commit
4cff0434e8
8 changed files with 31 additions and 21 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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" }
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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; }
|
||||
|
|
Loading…
Add table
Reference in a new issue