Skip to content

[clang] Union of a non-literal type and a literal type should be literal #77924

Closed
@groundswellaudio

Description

@groundswellaudio

Clang fails to compile this code :

https://godbolt.org/z/qvxGcPx6x

struct A {
    A();
};

template <class T>
struct opt
{
    union Data {
        
        constexpr Data() : x{} {}
        constexpr ~Data() {}

        char x;
        T data;
    };

    constexpr opt() : data{} {}
    constexpr ~opt() { if (engaged) data.data.~T(); }

    Data data;
    bool engaged = false;
};

consteval void foo()
{
    opt<A> a;
}

int main()
{
    foo();
}

With the error non-literal type 'opt<A>' cannot be used in a constant expression (in C++23, in C++20 the message is slightly different). opt<A> is not considered a literal type because of the implementation of CXXRecordDecl::isLiteral :

bool isLiteral() const {

which does not take into account that the CXXRecordDecl in question might be an union, in which case the type is literal if at least one of its member is literal. Perhaps the meaning of the bitfield hasNonLiteralTypeFieldsOrBases should change when the Decl is an union? since it does not seems to serve any other purposes than to detect whether the type is literal or not.

(this causes problem with the constexpr-isation of std::format which i'm currently working on)

Metadata

Metadata

Assignees

Labels

c++clang:frontendLanguage frontend issues, e.g. anything involving "Sema"confirmedVerified by a second party

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions