Skip to content

Commit e5bbc9f

Browse files
authored
[Clang] Fixes __builtin_is_implicit_lifetime for types with deleted ctrs (#161163)
We failed to check that the trivial constructor where eligible (this implies non deleted). Fixes #160610
1 parent b285bac commit e5bbc9f

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ Bug Fixes to C++ Support
432432
- Fix an assertion failure when taking the address on a non-type template parameter argument of
433433
object type. (#GH151531)
434434
- Suppress ``-Wdouble-promotion`` when explicitly asked for with C++ list initialization (#GH33409).
435+
- Fix the result of `__builtin_is_implicit_lifetime` for types with a user-provided constructor. (#GH160610)
435436

436437
Bug Fixes to AST Handling
437438
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,13 +1163,16 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
11631163
// - it has at least one trivial eligible constructor and a trivial,
11641164
// non-deleted destructor.
11651165
const CXXDestructorDecl *Dtor = RD->getDestructor();
1166-
if (UnqualT->isAggregateType())
1167-
if (Dtor && !Dtor->isUserProvided())
1168-
return true;
1169-
if (RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted()))
1170-
if (RD->hasTrivialDefaultConstructor() ||
1171-
RD->hasTrivialCopyConstructor() || RD->hasTrivialMoveConstructor())
1172-
return true;
1166+
if (UnqualT->isAggregateType() && (!Dtor || !Dtor->isUserProvided()))
1167+
return true;
1168+
if (RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted())) {
1169+
for (CXXConstructorDecl *Ctr : RD->ctors()) {
1170+
if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
1171+
continue;
1172+
if (Ctr->isTrivial())
1173+
return true;
1174+
}
1175+
}
11731176
return false;
11741177
}
11751178
case UTT_IsIntangibleType:

clang/test/SemaCXX/type-traits.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2038,6 +2038,49 @@ void is_implicit_lifetime(int n) {
20382038
static_assert(__builtin_is_implicit_lifetime(int * __restrict));
20392039
}
20402040

2041+
namespace GH160610 {
2042+
class NonAggregate {
2043+
public:
2044+
NonAggregate() = default;
2045+
2046+
NonAggregate(const NonAggregate&) = delete;
2047+
NonAggregate& operator=(const NonAggregate&) = delete;
2048+
private:
2049+
int num;
2050+
};
2051+
2052+
class DataMemberInitializer {
2053+
public:
2054+
DataMemberInitializer() = default;
2055+
2056+
DataMemberInitializer(const DataMemberInitializer&) = delete;
2057+
DataMemberInitializer& operator=(const DataMemberInitializer&) = delete;
2058+
private:
2059+
int num = 0;
2060+
};
2061+
2062+
class UserProvidedConstructor {
2063+
public:
2064+
UserProvidedConstructor() {}
2065+
2066+
UserProvidedConstructor(const UserProvidedConstructor&) = delete;
2067+
UserProvidedConstructor& operator=(const UserProvidedConstructor&) = delete;
2068+
};
2069+
2070+
static_assert(__builtin_is_implicit_lifetime(NonAggregate));
2071+
static_assert(!__builtin_is_implicit_lifetime(DataMemberInitializer));
2072+
static_assert(!__builtin_is_implicit_lifetime(UserProvidedConstructor));
2073+
2074+
#if __cplusplus >= 202002L
2075+
template <typename T>
2076+
class Tpl {
2077+
Tpl() requires false = default ;
2078+
};
2079+
static_assert(!__builtin_is_implicit_lifetime(Tpl<int>));
2080+
2081+
#endif
2082+
}
2083+
20412084
void is_signed()
20422085
{
20432086
//static_assert(__is_signed(char));

0 commit comments

Comments
 (0)