-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Closed as not planned
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"constexprAnything related to constant evaluationAnything related to constant evaluationquestionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!
Description
With the following code:
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="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2747r2.html">standard</A>:
* 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?
Metadata
Metadata
Assignees
Labels
clang:frontendLanguage frontend issues, e.g. anything involving "Sema"Language frontend issues, e.g. anything involving "Sema"constexprAnything related to constant evaluationAnything related to constant evaluationquestionA question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!A question, not bug report. Check out https://llvm.org/docs/GettingInvolved.html instead!