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.
20 lines
395 B
C
20 lines
395 B
C
// 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" }
|