[llvm-bugs] [Bug 45534] __builtin_constant_p ignores destructors with side-effects

via llvm-bugs llvm-bugs at lists.llvm.org
Mon Apr 20 21:25:52 PDT 2020


https://bugs.llvm.org/show_bug.cgi?id=45534

Richard Smith <richard-llvm at metafoo.co.uk> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
         Resolution|---                         |FIXED
             Status|NEW                         |RESOLVED

--- Comment #2 from Richard Smith <richard-llvm at metafoo.co.uk> ---
It turns out this has nothing to do with destructors; the same issue is visible
here:

int a;
static_assert(__builtin_constant_p(((void)++a, 1)));

We forgot to check whether we had skipped over unmodeled side-effects during
the evaluation of the operand of __builtin_constant_p.

We register an unmodeled side-effect when we create a temporary whose
destructor has side-effects as part of a speculative evaluation (such as the
evaluation of the operand of __builtin_constant_p). That means that we now
reject this example that GCC accepts:

struct A { constexpr A() {} constexpr ~A() {} };
static_assert(__builtin_constant_p( A{}, 0 ));

but GCC appears to be doing something that doesn't seem entirely reasonable to
follow: it's registering the destructor and running it at the end of the
enclosing full-expression instead. This can be seen in an example such as:

struct X { int *p; constexpr ~X() { *p = 0; } };
static_assert(!__builtin_constant_p((X{}, 1)));

... which GCC rejects saying the expression is not constant (because the
destructor call happens outside the protection of the __builtin_constant_p) and
in a similar example such as:

int a;
static_assert(__builtin_constant_p((X{}, 1)) && a);

... for which GCC complains about the non-constant read from 'a', not the
non-constant store through '*p' in the destructor, which similarly shows the
destructor call is evaluated *after* the `&& a`.

That seems worse than Clang's choice, and doesn't seem like reasonable behavior
to follow. If GCC switches to something more sensible (such as destroying the
temporaries at the end of evaluating the __builtin_constant_p argument), we can
follow that behavior.

Fixed in llvmorg-11-init-12497-g4b03dd7b849.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200421/c2d9b34d/attachment.html>


More information about the llvm-bugs mailing list