Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions clang/lib/Sema/SemaTypeTraits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1165,14 +1165,30 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
const CXXDestructorDecl *Dtor = RD->getDestructor();
if (UnqualT->isAggregateType() && (!Dtor || !Dtor->isUserProvided()))
return true;
if (RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted())) {
for (CXXConstructorDecl *Ctr : RD->ctors()) {
if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
continue;
if (Ctr->isTrivial())
return true;
}
if (!(RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted())))
return false;
if (RD->hasTrivialDefaultConstructor())
return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UTT_HasTrivialDefaultConstructor handler checks RD->hasTrivialDefaultConstructor() && !RD->hasNonTrivialDefaultConstructor() for some reason. Not sure if this is really needed.

bool FoundCopyCtr = false;
bool FoundMoveCtr = false;
bool FoundDefaultCtr = false;
for (CXXConstructorDecl *Ctr : RD->ctors()) {
if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
continue;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test fails now because short-circuiting here occurs before FoundCopyCtr can be set.

if (Ctr->isTrivial())
return true;
FoundCopyCtr = Ctr->isCopyConstructor();
FoundMoveCtr = Ctr->isMoveConstructor();
FoundDefaultCtr = Ctr->isDefaultConstructor();
}
if (!FoundDefaultCtr && RD->hasTrivialDefaultConstructor())
return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is never reached because RD->hasTrivialDefaultConstructor() == true case has been short-circuited above.

if (!FoundCopyCtr && RD->hasTrivialCopyConstructor() &&
!RD->defaultedCopyConstructorIsDeleted())
return true;
if (!FoundMoveCtr && RD->hasTrivialMoveConstructor() &&
!RD->defaultedMoveConstructorIsDeleted())
return true;
return false;
}
case UTT_IsIntangibleType:
Expand Down
22 changes: 21 additions & 1 deletion clang/test/SemaCXX/type-traits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2066,7 +2066,27 @@ class UserProvidedConstructor {
UserProvidedConstructor(const UserProvidedConstructor&) = delete;
UserProvidedConstructor& operator=(const UserProvidedConstructor&) = delete;
};
struct Ctr {
Ctr();
};
struct Ctr2 {
Ctr2();
private:
NoEligibleTrivialContructor inner;
};

struct NonCopyable{
NonCopyable() = default;
NonCopyable(const NonCopyable&) = delete;
};

class C {
NonCopyable nc;
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to add a note that the classes should not be used here in any way causing declarations of the implicit methods to be instantiated (or whatever the correct word is).


static_assert(__builtin_is_implicit_lifetime(Ctr));
static_assert(__builtin_is_implicit_lifetime(C));
static_assert(!__builtin_is_implicit_lifetime(NoEligibleTrivialContructor));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ctr2 is not used in this test. Maybe, you wanted to mention it here instead of NoEligibleTrivialContructor?

static_assert(__builtin_is_implicit_lifetime(NonAggregate));
static_assert(!__builtin_is_implicit_lifetime(DataMemberInitializer));
static_assert(!__builtin_is_implicit_lifetime(UserProvidedConstructor));
Expand All @@ -2076,7 +2096,7 @@ template <typename T>
class Tpl {
Tpl() requires false = default ;
};
static_assert(!__builtin_is_implicit_lifetime(Tpl<int>));
static_assert(__builtin_is_implicit_lifetime(Tpl<int>));

#endif
}
Expand Down
Loading