| Issue |
63445
|
| Summary |
member call on member 'data_' of union with no active member is not allowed in a constant _expression_
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
z0nt
|
Clang refuses to compile the following code:
```c++
#include <stdlib.h>
template <class T, int N>
class Array {
public:
template <typename... Args>
constexpr Array(Args... args) noexcept {
static_assert(sizeof...(args) <= N);
ArrayBuilder(args...);
}
constexpr void push_back(const T& value) noexcept {
if (size_ < N) {
data_[size_++] = value;
} else {
abort();
}
}
constexpr int size() const { return size_; }
constexpr const T& operator[](int pos) const { return data_[pos]; }
private:
constexpr void ArrayBuilder() noexcept { }
template <typename _T, typename... Args>
constexpr void ArrayBuilder(_T value, Args... args) noexcept {
data_[size_++] = value;
ArrayBuilder(args...);
}
int size_ = 0;
union {
T data_[N];
};
};
class Int {
public:
Int() = delete;
constexpr explicit Int(int i) noexcept : i_(i) {}
constexpr operator int() const { return i_; }
private:
//int i_; // works
int i_ = 0; // doesn't compile
};
static constexpr Array<Int, 1> GetInts() {
Array<Int, 1> ret;
ret.push_back(Int(0x5a));
return ret;
}
//static constexpr Array<Int, 1> GetInts() { return {Int(0x5a)}; }
//static constexpr Array<int, 1> GetInts() { return {int(0x5a)}; }
int main() {
constexpr auto test = GetInts();
static_assert(test.size() == 1);
static_assert(test[0] == 0x5a);
}
```
with the following diagnostic:
```
main.cc:59:18: error: constexpr variable 'test' must be initialized by a constant _expression_
constexpr auto test = GetInts();
^ ~~~~~~~~~
main.cc:14:22: note: member call on member 'data_' of union with no active member is not allowed in a constant _expression_
data_[size_++] = value;
^
main.cc:52:7: note: in call to '&ret->push_back(Int(90))'
ret.push_back(Int(0x5a));
^
main.cc:59:25: note: in call to 'GetInts()'
constexpr auto test = GetInts();
^
```
Compiles just fine with GCC & MSVC -- https://godbolt.org/z/5qdh7cq6a
Eventually I've made code compiling with Clang. The only change I've made is removed default initialization of member of`class Int` (which should not make any difference at all, because there is explicit constructor and default one is deleted). There is also different version of `GetInts()` which uses template parameter pack, but it fails to compile as well (though GCC & MSVC compile it as well with no problem).
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs