[clang] [Clang] Fix a regression introduced by #161163. (PR #162612)
Corentin Jabot via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 10 05:57:44 PDT 2025
https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/162612
>From af13d31f970cc62d46746b5e57075f16c5f5c4e8 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Thu, 9 Oct 2025 10:18:28 +0200
Subject: [PATCH 1/4] [Clang] Fix a regression introduced by #161163.
Classes with a user provided constructor are still implicit lifetime
if they have an implicit, trivial copy ctr.
---
clang/lib/Sema/SemaTypeTraits.cpp | 24 +++++++++++++++++-------
clang/test/SemaCXX/type-traits.cpp | 12 +++++++++++-
2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp
index 3e34675cbf064..13f25c453d8ba 100644
--- a/clang/lib/Sema/SemaTypeTraits.cpp
+++ b/clang/lib/Sema/SemaTypeTraits.cpp
@@ -1165,14 +1165,24 @@ 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;
+ bool FoundCopyCtr = false;
+ bool FoundMoveCtr = false;
+ for (CXXConstructorDecl *Ctr : RD->ctors()) {
+ FoundCopyCtr = Ctr->isCopyConstructor();
+ FoundMoveCtr = Ctr->isMoveConstructor();
+ if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
+ continue;
+ if (Ctr->isTrivial())
+ return true;
}
+ if (!FoundCopyCtr && RD->hasTrivialCopyConstructor() &&
+ !RD->defaultedCopyConstructorIsDeleted())
+ return true;
+ if (!FoundMoveCtr && RD->hasTrivialMoveConstructor() &&
+ !RD->defaultedMoveConstructorIsDeleted())
+ return true;
return false;
}
case UTT_IsIntangibleType:
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 901d510bba847..343529fe81b57 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -2066,7 +2066,17 @@ class UserProvidedConstructor {
UserProvidedConstructor(const UserProvidedConstructor&) = delete;
UserProvidedConstructor& operator=(const UserProvidedConstructor&) = delete;
};
+struct Ctr {
+ Ctr();
+};
+struct Ctr2 {
+ Ctr2();
+private:
+ NoEligibleTrivialContructor inner;
+};
+static_assert(__builtin_is_implicit_lifetime(Ctr));
+static_assert(!__builtin_is_implicit_lifetime(NoEligibleTrivialContructor));
static_assert(__builtin_is_implicit_lifetime(NonAggregate));
static_assert(!__builtin_is_implicit_lifetime(DataMemberInitializer));
static_assert(!__builtin_is_implicit_lifetime(UserProvidedConstructor));
@@ -2076,7 +2086,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
}
>From 32f2664975e61c3368a4d47a10bb992c2572edd5 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Thu, 9 Oct 2025 18:24:41 +0200
Subject: [PATCH 2/4] fix the case of non copyable subobjects
---
clang/lib/Sema/SemaTypeTraits.cpp | 10 ++++++++--
clang/test/SemaCXX/type-traits.cpp | 10 ++++++++++
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp
index 13f25c453d8ba..187d39e8f26ed 100644
--- a/clang/lib/Sema/SemaTypeTraits.cpp
+++ b/clang/lib/Sema/SemaTypeTraits.cpp
@@ -1167,16 +1167,22 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
return true;
if (!(RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted())))
return false;
+ if (RD->hasTrivialDefaultConstructor())
+ return true;
bool FoundCopyCtr = false;
bool FoundMoveCtr = false;
+ bool FoundDefaultCtr = false;
for (CXXConstructorDecl *Ctr : RD->ctors()) {
- FoundCopyCtr = Ctr->isCopyConstructor();
- FoundMoveCtr = Ctr->isMoveConstructor();
if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
continue;
if (Ctr->isTrivial())
return true;
+ FoundCopyCtr = Ctr->isCopyConstructor();
+ FoundMoveCtr = Ctr->isMoveConstructor();
+ FoundDefaultCtr = Ctr->isDefaultConstructor();
}
+ if (!FoundDefaultCtr && RD->hasTrivialDefaultConstructor())
+ return true;
if (!FoundCopyCtr && RD->hasTrivialCopyConstructor() &&
!RD->defaultedCopyConstructorIsDeleted())
return true;
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 343529fe81b57..bc010dc5932ca 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -2075,7 +2075,17 @@ struct Ctr2 {
NoEligibleTrivialContructor inner;
};
+struct NonCopyable{
+ NonCopyable() = default;
+ NonCopyable(const NonCopyable&) = delete;
+};
+
+class C {
+ NonCopyable nc;
+};
+
static_assert(__builtin_is_implicit_lifetime(Ctr));
+static_assert(__builtin_is_implicit_lifetime(C));
static_assert(!__builtin_is_implicit_lifetime(NoEligibleTrivialContructor));
static_assert(__builtin_is_implicit_lifetime(NonAggregate));
static_assert(!__builtin_is_implicit_lifetime(DataMemberInitializer));
>From 189c4a1105d7ba407904b0fa6cc3769bcb6f308a Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Fri, 10 Oct 2025 13:31:48 +0200
Subject: [PATCH 3/4] more fixes + cleanup + add missing tests
---
clang/lib/Sema/SemaTypeTraits.cpp | 16 +++++-----------
clang/test/SemaCXX/type-traits.cpp | 5 +++--
2 files changed, 8 insertions(+), 13 deletions(-)
diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp
index 187d39e8f26ed..d4cecaaac8c64 100644
--- a/clang/lib/Sema/SemaTypeTraits.cpp
+++ b/clang/lib/Sema/SemaTypeTraits.cpp
@@ -1167,26 +1167,20 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
return true;
if (!(RD->hasTrivialDestructor() && (!Dtor || !Dtor->isDeleted())))
return false;
- if (RD->hasTrivialDefaultConstructor())
- return true;
- bool FoundCopyCtr = false;
- bool FoundMoveCtr = false;
- bool FoundDefaultCtr = false;
for (CXXConstructorDecl *Ctr : RD->ctors()) {
if (Ctr->isIneligibleOrNotSelected() || Ctr->isDeleted())
continue;
if (Ctr->isTrivial())
return true;
- FoundCopyCtr = Ctr->isCopyConstructor();
- FoundMoveCtr = Ctr->isMoveConstructor();
- FoundDefaultCtr = Ctr->isDefaultConstructor();
}
- if (!FoundDefaultCtr && RD->hasTrivialDefaultConstructor())
+ if (RD->needsImplicitDefaultConstructor() &&
+ RD->hasTrivialDefaultConstructor() &&
+ !RD->hasNonTrivialDefaultConstructor())
return true;
- if (!FoundCopyCtr && RD->hasTrivialCopyConstructor() &&
+ if (RD->needsImplicitCopyConstructor() && RD->hasTrivialCopyConstructor() &&
!RD->defaultedCopyConstructorIsDeleted())
return true;
- if (!FoundMoveCtr && RD->hasTrivialMoveConstructor() &&
+ if (RD->needsImplicitMoveConstructor() && RD->hasTrivialMoveConstructor() &&
!RD->defaultedMoveConstructorIsDeleted())
return true;
return false;
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index bc010dc5932ca..47fe6e5119767 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -2067,10 +2067,10 @@ class UserProvidedConstructor {
UserProvidedConstructor& operator=(const UserProvidedConstructor&) = delete;
};
struct Ctr {
- Ctr();
+ Ctr();
};
struct Ctr2 {
- Ctr2();
+ Ctr2();
private:
NoEligibleTrivialContructor inner;
};
@@ -2085,6 +2085,7 @@ class C {
};
static_assert(__builtin_is_implicit_lifetime(Ctr));
+static_assert(!__builtin_is_implicit_lifetime(Ctr2));
static_assert(__builtin_is_implicit_lifetime(C));
static_assert(!__builtin_is_implicit_lifetime(NoEligibleTrivialContructor));
static_assert(__builtin_is_implicit_lifetime(NonAggregate));
>From 8dd01f8e1019cfda9607f276ca97c08a3569c5d6 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Fri, 10 Oct 2025 14:57:28 +0200
Subject: [PATCH 4/4] more tests for constrained default constructors
---
clang/lib/Sema/SemaTypeTraits.cpp | 3 +--
clang/test/SemaCXX/type-traits.cpp | 18 ++++++++++++++++++
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp
index d4cecaaac8c64..e4d055fd31301 100644
--- a/clang/lib/Sema/SemaTypeTraits.cpp
+++ b/clang/lib/Sema/SemaTypeTraits.cpp
@@ -1076,8 +1076,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
if (T.isPODType(C) || T->isObjCLifetimeType())
return true;
if (CXXRecordDecl *RD = C.getBaseElementType(T)->getAsCXXRecordDecl()) {
- if (RD->hasTrivialDefaultConstructor() &&
- !RD->hasNonTrivialDefaultConstructor())
+ if (RD->hasTrivialDefaultConstructor())
return true;
bool FoundConstructor = false;
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 47fe6e5119767..9ef44d0346b48 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -2099,7 +2099,25 @@ class Tpl {
};
static_assert(__builtin_is_implicit_lifetime(Tpl<int>));
+template <typename>
+class MultipleDefaults {
+ MultipleDefaults() {};
+ MultipleDefaults() requires true = default;
+};
+static_assert(__builtin_is_implicit_lifetime(MultipleDefaults<int>));
+template <typename>
+class MultipleDefaults2 {
+ MultipleDefaults2() requires true {};
+ MultipleDefaults2() = default;
+};
+
+static_assert(__builtin_is_implicit_lifetime(MultipleDefaults2<int>));
+
+
#endif
+
+
+
}
void is_signed()
More information about the cfe-commits
mailing list