Issue 83409
Summary clang: initialization with assignment _expression_ possibly triggers wrong template instantiation
Labels clang
Assignees
Reporter bebuch
    ```cpp
template <typename T>
struct holder {
    holder() = default;

 constexpr ~holder() {
        static_assert(sizeof(T) || true);
 }
};

struct Incomplete;

struct Class {
    Class();
 ~Class();

    holder<Incomplete> a{};                      // Reject: MSVC;            Accept: GCC, clang
    holder<Incomplete> b = {}; // Reject: MSVC, GCC;       Accept: clang
    holder<Incomplete> c = holder<Incomplete>{}; // Reject: MSVC, GCC, clang
};

int main() {
    [[maybe_unused]] Class v;
}
```

Live Code: [Case `a`](https://godbolt.org/z/cYWTTMeoa), [Case `b`](https://godbolt.org/z/xf45795b1), [Case `c`](https://godbolt.org/z/Y764zPqKa).

I assume that all 3 cases should be valid in C++20/23, but I'm not sure.

Note that this compiles fine with MSVC and GCC, only clang reject:

```cpp
template <typename T>
struct holder {
    holder() = default;

 constexpr ~holder() {
        static_assert(sizeof(T) || true);
 }
};

struct Incomplete;

template <typename=void> // make Class a template
struct Class {
    Class();
    ~Class();

 holder<Incomplete> a{};
    holder<Incomplete> b = {};
 holder<Incomplete> c = holder<Incomplete>{};
};

int main() {
 [[maybe_unused]] Class v;
}
```

[Live Code](https://godbolt.org/z/1so75fa5x)

There are these Bug reports to MSVC:

- https://developercommunity.visualstudio.com/t/10514504
- https://github.com/microsoft/STL/issues/4417
- https://developercommunity.visualstudio.com/t/10604135

And this one to GCC:

- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114076

Note comment from Jiang An:

> I don't see why there's even a temporary value [in case `c`] since C++17. The prvalue is used to initialize the data member (via temporary materialization). The potential invocation of destructor should be in the body of constructors.

I also asked about this at StackOverflow:

- https://stackoverflow.com/questions/78040562

The original `holder` class template was `std::unique_ptr`, which became `constexpr` in C++23.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to