Skip to content

[Clang] __builtin_is_implicit_lifetime isn't checking for trivial constructors #160610

@StephanTLavavej

Description

@StephanTLavavej

Repros with Clang 20.1.8:

C:\Temp>type meow.cpp
class NonAggregate {
public:
    NonAggregate() = default;

    NonAggregate(const NonAggregate&)            = delete;
    NonAggregate& operator=(const NonAggregate&) = delete;

    void set_num(int x) {
        num = x;
    }
    int get_num() const {
        return num;
    }

private:
    int num;
};

class DataMemberInitializer {
public:
    DataMemberInitializer() = default;

    DataMemberInitializer(const DataMemberInitializer&)            = delete;
    DataMemberInitializer& operator=(const DataMemberInitializer&) = delete;

    void set_num(int x) {
        num = x;
    }
    int get_num() const {
        return num;
    }

private:
    int num{0};
};

class UserProvidedConstructor {
public:
    UserProvidedConstructor() {}

    UserProvidedConstructor(const UserProvidedConstructor&)            = delete;
    UserProvidedConstructor& operator=(const UserProvidedConstructor&) = delete;

    void set_num(int x) {
        num = x;
    }
    int get_num() const {
        return num;
    }

private:
    int num;
};

// N5014 [dcl.init.aggr]/1.2:
// "An aggregate is an array or a class (Clause 11) with [...]
// no private or protected direct non-static data members (11.8),"

// N5014 [class.default.ctor]/3:
// "A default constructor for a class X is trivial if it is not user-provided and if [...]
// - no non-static data member of X has a default member initializer (11.4), and [...]
// Otherwise, the default constructor is non-trivial."

// N5014 [class.prop]/16:
// "A class S is an implicit-lifetime class if
// - it is an aggregate whose destructor is not user-provided or
// - it has at least one trivial eligible constructor and a trivial, non-deleted destructor."

static_assert(__builtin_is_implicit_lifetime(NonAggregate));
static_assert(!__builtin_is_implicit_lifetime(DataMemberInitializer));
static_assert(!__builtin_is_implicit_lifetime(UserProvidedConstructor));
C:\Temp>clang-cl -v
clang version 20.1.8
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\Microsoft Visual Studio\18\Insiders\VC\Tools\Llvm\x64\bin

C:\Temp>clang-cl /EHsc /nologo /W4 /std:c++latest /c meow.cpp
meow.cpp(70,15): error: static assertion failed due to requirement
      '!__builtin_is_implicit_lifetime(DataMemberInitializer)'
   70 | static_assert(!__builtin_is_implicit_lifetime(DataMemberInitializer));
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
meow.cpp(71,15): error: static assertion failed due to requirement
      '!__builtin_is_implicit_lifetime(UserProvidedConstructor)'
   71 | static_assert(!__builtin_is_implicit_lifetime(UserProvidedConstructor));
      |               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.

(Updated repro to make the classes noncopyable, ruling out any involvement of copy constructors. Thanks @frederick-vs-ja for bringing that to my attention.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions