Skip to content

Commit bcf9e91

Browse files
authored
[Clang] Fix a regression introduced by #161163. (#162612)
Classes with a user provided constructor are still implicit lifetime if they have an implicit, trivial copy ctr.
1 parent 8395a36 commit bcf9e91

File tree

2 files changed

+60
-10
lines changed

2 files changed

+60
-10
lines changed

clang/lib/Sema/SemaTypeTraits.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,8 +1076,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
10761076
if (T.isPODType(C) || T->isObjCLifetimeType())
10771077
return true;
10781078
if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
1079-
if (RD->hasTrivialDefaultConstructor() &&
1080-
!RD->hasNonTrivialDefaultConstructor())
1079+
if (RD->hasTrivialDefaultConstructor())
10811080
return true;
10821081

10831082
bool FoundConstructor = false;
@@ -1165,14 +1164,26 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
11651164
const CXXDestructorDecl *Dtor = RD->getDestructor();
11661165
if (UnqualT->isAggregateType() && (!Dtor || !Dtor->isUserProvided()))
11671166
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-
}
1167+
bool HasTrivialNonDeletedDtr =
1168+
RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted());
1169+
if (!HasTrivialNonDeletedDtr)
1170+
return false;
1171+
for (CXXConstructorDecl *Ctr : RD->ctors()) {
1172+
if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
1173+
continue;
1174+
if (Ctr->isTrivial())
1175+
return true;
11751176
}
1177+
if (RD->needsImplicitDefaultConstructor() &&
1178+
RD->hasTrivialDefaultConstructor() &&
1179+
!RD->hasNonTrivialDefaultConstructor())
1180+
return true;
1181+
if (RD->needsImplicitCopyConstructor() && RD->hasTrivialCopyConstructor() &&
1182+
!RD->defaultedCopyConstructorIsDeleted())
1183+
return true;
1184+
if (RD->needsImplicitMoveConstructor() && RD->hasTrivialMoveConstructor() &&
1185+
!RD->defaultedMoveConstructorIsDeleted())
1186+
return true;
11761187
return false;
11771188
}
11781189
case UTT_IsIntangibleType:

clang/test/SemaCXX/type-traits.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2066,7 +2066,28 @@ class UserProvidedConstructor {
20662066
UserProvidedConstructor(const UserProvidedConstructor&) = delete;
20672067
UserProvidedConstructor& operator=(const UserProvidedConstructor&) = delete;
20682068
};
2069+
struct Ctr {
2070+
Ctr();
2071+
};
2072+
struct Ctr2 {
2073+
Ctr2();
2074+
private:
2075+
NoEligibleTrivialContructor inner;
2076+
};
2077+
2078+
struct NonCopyable{
2079+
NonCopyable() = default;
2080+
NonCopyable(const NonCopyable&) = delete;
2081+
};
2082+
2083+
class C {
2084+
NonCopyable nc;
2085+
};
20692086

2087+
static_assert(__builtin_is_implicit_lifetime(Ctr));
2088+
static_assert(!__builtin_is_implicit_lifetime(Ctr2));
2089+
static_assert(__builtin_is_implicit_lifetime(C));
2090+
static_assert(!__builtin_is_implicit_lifetime(NoEligibleTrivialContructor));
20702091
static_assert(__builtin_is_implicit_lifetime(NonAggregate));
20712092
static_assert(!__builtin_is_implicit_lifetime(DataMemberInitializer));
20722093
static_assert(!__builtin_is_implicit_lifetime(UserProvidedConstructor));
@@ -2076,9 +2097,27 @@ template <typename T>
20762097
class Tpl {
20772098
Tpl() requires false = default ;
20782099
};
2079-
static_assert(!__builtin_is_implicit_lifetime(Tpl<int>));
2100+
static_assert(__builtin_is_implicit_lifetime(Tpl<int>));
2101+
2102+
template <typename>
2103+
class MultipleDefaults {
2104+
MultipleDefaults() {};
2105+
MultipleDefaults() requires true = default;
2106+
};
2107+
static_assert(__builtin_is_implicit_lifetime(MultipleDefaults<int>));
2108+
template <typename>
2109+
class MultipleDefaults2 {
2110+
MultipleDefaults2() requires true {};
2111+
MultipleDefaults2() = default;
2112+
};
2113+
2114+
static_assert(__builtin_is_implicit_lifetime(MultipleDefaults2<int>));
2115+
20802116

20812117
#endif
2118+
2119+
2120+
20822121
}
20832122

20842123
void is_signed()

0 commit comments

Comments
 (0)