| Issue |
162589
|
| Summary |
avoid error 'placement new would change type of storage'
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
cppljevans
|
With the following code:
```c++
template
< unsigned I
>
struct
type
{
constexpr
type(){}
};
#include <cstddef>//std::byte
#include <algorithm>//for std::max
template
< typename... T
>
union
uninitialized_T0
/**<@brief
* A buffer for stoarge of a
* variant of types T...
*/
{
constexpr uninitialized_T0() noexcept {}
uninitialized_T0(const uninitialized_T0&) = delete;
uninitialized_T0& operator=(const uninitialized_T0&) = delete;
constexpr ~uninitialized_T0() noexcept {}
static constexpr size_t
Size = std::max( { sizeof( T)...})
;
alignas(T...)
std::byte
buffer[Size]{}
/**<@brief
* Storage for any of T... with proper alignment for all.
*/
;
constexpr void*
voidify()
{ return buffer
;}
//#define EXPLICIT_TYPE0
#ifdef EXPLICIT_TYPE0
type<0>
t0
/**<@brief
* The only reason for this is to show the
* absurdity, in one sense, of the error when
* defined(USE_BUFFER) && defined(USE_CONSTEXPR).
*
* The error is not absurd in another sense because
* it conforms to the <A HREF=""
* saying(at "(5.14)"):
* "unless P points to an object whose type is similar to T;"
* and std::byte[Size] is NOT similar to type<0>.
*
* OTOH, it is absurd because the purpose of this union is to provide
* an uninitialized buffer in which to placement new a type, T, whose
* "alignment and size requirements" are "compatible"
* with that of the buffer's.
*
* Note, "alignment and size requirements" means alignas(T) and sizeof(T).
*
* The constraint, "similar to" should be irrelevant, in this case.
*/
;
#endif//EXPLICIT_TYPE0
};
#include <new>
template
< typename... T
>
struct
variant
{
private:
uninitialized_T0
< T...
>
storage
;
public:
constexpr
variant()
{
; new
#ifdef EXPLICIT_TYPE0
( &storage.t0
//with clang++20, WHEN defined(USE_CONSTEXPR),
//this compiles without error.
#else
( storage.voidify()
//with clang++20, WHEN defined(USE_CONSTEXPR),
//this causes error:
// error: constexpr variable 'v' must be initialized by a constant _expression_
// note: placement new would change type of storage from 'std::byte' to 'type<0>'
#endif//EXPLICIT_TYPE0
)
type<0>
;}
};
int
main()
{
variant<type<0>,type<1>,type<2>>
#define USE_CONSTEXPR
#ifdef USE_CONSTEXPR
constexpr
#endif//USE_CONSTEXPR
v
; return 0
;}
```
When:
`defined(USE_CONSTEXPR)` and `!defined(EXPLICIT_T0)`
as explained in the comments, `clang++-20 -std=c++26` produces the error shown in the comments.
However, when:
`defined(USE_CONSTEXPR)` and `defined(EXPLICIT_T0)`
No error is produced.
Is there someway to disable the error about:
`placement new would change type of storage`
? If not, is there some code modification to disable that error message in
this particular case? If so, where is that code?
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs