c++: Fix constexpr cleanup error handling.
In this testcase, the primary evaluation successfully produces 'true', and then running one of the cleanups hits a double delete, making the whole thing not a valid constant expression. So we were returning 'true' wrapped in a NOP_EXPR to indicate its non-constancy, but evaluating that again is a perfectly acceptable constant expression, so we weren't getting the verbose diagnostic we were looking for. So if non_constant_p gets set other than for overflow, go back to the original expression. With this change, we should never hit the manifestly_const_eval test, and the is-constant-evaluated1.C test passes without it. gcc/cp/ChangeLog: PR c++/97388 * constexpr.c (cxx_eval_outermost_constant_expr): Revert to original expression if evaluation sets non_constant_p. gcc/testsuite/ChangeLog: PR c++/97388 * g++.dg/cpp2a/constexpr-dtor8.C: New test.
This commit is contained in:
parent
5afd90c5f3
commit
8895443a42
@ -6925,6 +6925,10 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
|
||||
non_constant_p = true;
|
||||
}
|
||||
|
||||
if (non_constant_p)
|
||||
/* If we saw something bad, go back to our argument. The wrapping below is
|
||||
only for the cases of TREE_CONSTANT argument or overflow. */
|
||||
r = t;
|
||||
|
||||
if (!non_constant_p && overflow_p)
|
||||
non_constant_p = true;
|
||||
@ -6941,12 +6945,6 @@ cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
|
||||
return r;
|
||||
else if (non_constant_p && TREE_CONSTANT (r))
|
||||
{
|
||||
/* If __builtin_is_constant_evaluated () was evaluated to true
|
||||
and the result is not a valid constant expression, we need to
|
||||
punt. */
|
||||
if (manifestly_const_eval)
|
||||
return cxx_eval_outermost_constant_expr (t, true, strict,
|
||||
false, false, object);
|
||||
/* This isn't actually constant, so unset TREE_CONSTANT.
|
||||
Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires
|
||||
it to be set if it is invariant address, even when it is not
|
||||
|
19
gcc/testsuite/g++.dg/cpp2a/constexpr-dtor8.C
Normal file
19
gcc/testsuite/g++.dg/cpp2a/constexpr-dtor8.C
Normal file
@ -0,0 +1,19 @@
|
||||
// PR c++/97388
|
||||
// { dg-do compile { target c++20 } }
|
||||
|
||||
struct S {
|
||||
int *s;
|
||||
constexpr S () : s(new int) {}
|
||||
S (const S &) = delete;
|
||||
S &operator= (const S &) = delete;
|
||||
constexpr ~S () { delete s; } // { dg-error "already deallocated" }
|
||||
};
|
||||
|
||||
constexpr bool
|
||||
foo (S v)
|
||||
{
|
||||
delete v.s;
|
||||
return true;
|
||||
}
|
||||
|
||||
static_assert (foo (S ())); // { dg-error "non-constant condition for static assertion" }
|
Loading…
x
Reference in New Issue
Block a user