Issue 177791
Summary [Clang] Trivial copy constructor of classes with a `nullptr_t` member tries to read it during constant expressions
Labels clang
Assignees
Reporter MitalAshok
    An lvalue-to-rvalue conversion on a `nullptr_t` glvalue doesn't actually read it and should always produce a null pointer constant ([[conv.lval]p(3.1)](https://wg21.link/conv.lval#3.1)).

The implicitly defined copy constructor for a class should perform a memberwise copy. So there should be similar behaviour regardless of the `EXPLICIT_CONSTRUCTORS` macro in the following: (<https://godbolt.org/z/Tzqxxc15j>)

```c++
struct X {
#ifdef EXPLICIT_CONSTRUCTORS
    constexpr X() noexcept {}
 constexpr X(const X& other) noexcept : n(other.n) {}
#endif
 decltype(nullptr) n;
};

int main() {
    X x;
    void* p = &x;
 void* q = &x;
    __builtin_memcpy(&x.n, &p, sizeof p);
    X y = x;
 __builtin_memcpy(&p, &y.n, sizeof p);
    return __builtin_memcmp(&p, &q, sizeof p) == 0 ? 1 : 0;
}
```

When `EXPLICIT_CONSTRUCTORS` is defined, the program returns 1 (as expected, `n(other.n)` initialises it with a null pointer constant without reading), but when it is not defined, the program returns 0 (The 'trivial' copy constructor does a bytewise copy).

This is not entirely a bug, it's technically just a missed optimisation because the object representation of `nullptr_t` objects is not specified (so can be treated as all padding, also discussed in #167613). It might become an issue if the `nullptr` is volatile (and so shouldn't be read). It is an issue in a constant _expression_ (where it is explicitly allowed to perform lvalue-to-rvalue on any `std::nullptr_t` glvalue, [[expr.const]p(9.9.1)](https://wg21.link/expr.const#9.9.1)): (<https://godbolt.org/z/Kexoczzb8>)

```c++
struct X {
#ifdef EXPLICIT_CONSTRUCTORS
    constexpr X() noexcept {}
    constexpr X(const X& other) noexcept : n(other.n) {}
#endif
    decltype(nullptr) n;
};

extern X x;
constexpr X y = x;  // Only compiles with EXPLICIT_CONSTRUCTORS defined
```

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to