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

Reply via email to