[clang] [clang] __is_trivially_equality_comparable for types containing lambdas (PR #68506)
Amirreza Ashouri via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 7 23:18:26 PDT 2023
https://github.com/AMP999 created https://github.com/llvm/llvm-project/pull/68506
Lambdas (closure types) are trivially equality-comparable iff they are
non-capturing, because non-capturing lambdas are convertible to function
pointers: if (lam1 == lam2) compiles, then lam1 and lam2 must have
the same type, and be always-equal, and be empty.
>From ae2cd56b1c68353aae6c74524e71973ce6ca6904 Mon Sep 17 00:00:00 2001
From: Amirreza Ashouri <ar.ashouri999 at gmail.com>
Date: Sat, 7 Oct 2023 19:02:34 +0330
Subject: [PATCH 1/2] [clang] Rename some misleading names (Non-functional)
These names could be misleading; should we change them to
`NonTriviallyComparable` instead?
---
clang/test/SemaCXX/type-traits.cpp | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index a35689d52978fcc..a1315f1966a6dd4 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -3160,11 +3160,18 @@ static_assert(!__is_trivially_equality_comparable(float), "");
static_assert(!__is_trivially_equality_comparable(double), "");
static_assert(!__is_trivially_equality_comparable(long double), "");
-struct TriviallyEqualityComparableNoDefaultedComparator {
+struct NonTriviallyEqualityComparableNoComparator {
int i;
int j;
};
-static_assert(!__is_trivially_equality_comparable(TriviallyEqualityComparableNoDefaultedComparator), "");
+static_assert(!__is_trivially_equality_comparable(NonTriviallyEqualityComparableNoComparator), "");
+
+struct NonTriviallyEqualityComparableNonDefaultedComparator {
+ int i;
+ int j;
+ bool operator==(const NonTriviallyEqualityComparableNonDefaultedComparator&);
+};
+static_assert(!__is_trivially_equality_comparable(NonTriviallyEqualityComparableNonDefaultedComparator), "");
#if __cplusplus >= 202002L
@@ -3177,7 +3184,7 @@ struct TriviallyEqualityComparable {
bool operator==(const TriviallyEqualityComparable&) const = default;
};
-static_assert(__is_trivially_equality_comparable(TriviallyEqualityComparable), "");
+static_assert(__is_trivially_equality_comparable(TriviallyEqualityComparable));
struct TriviallyEqualityComparableContainsArray {
int a[4];
>From ef0ad97b1dee9f4d7547f551b4b8b96a51221c51 Mon Sep 17 00:00:00 2001
From: Amirreza Ashouri <ar.ashouri999 at gmail.com>
Date: Sat, 7 Oct 2023 19:07:32 +0330
Subject: [PATCH 2/2] [clang] __is_trivially_equality_comparable for types
containing lambdas
Lambdas (closure types) are trivially equality-comparable iff they are
non-capturing, because non-capturing lambdas are convertible to function
pointers: if (lam1 == lam2) compiles, then lam1 and lam2 must have
the same type, and be always-equal, and be empty.
---
clang/lib/AST/Type.cpp | 2 ++
clang/test/SemaCXX/type-traits.cpp | 11 +++++++++++
2 files changed, 13 insertions(+)
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 4c433f7fe9daca0..f0e419de3b1ee84 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2663,6 +2663,8 @@ static bool
HasNonDeletedDefaultedEqualityComparison(const CXXRecordDecl *Decl) {
if (Decl->isUnion())
return false;
+ if (Decl->isLambda())
+ return Decl->captures().empty() && (Decl->getLambdaCaptureDefault() == LCD_None);
auto IsDefaultedOperatorEqualEqual = [&](const FunctionDecl *Function) {
return Function->getOverloadedOperator() ==
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index a1315f1966a6dd4..275ddcbae73930d 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -3200,6 +3200,17 @@ struct TriviallyEqualityComparableContainsMultiDimensionArray {
};
static_assert(__is_trivially_equality_comparable(TriviallyEqualityComparableContainsMultiDimensionArray));
+auto GetNonCapturingLambda() { return [](){ return 42; }; }
+
+struct TriviallyEqualityComparableContainsLambda {
+ [[no_unique_address]] decltype(GetNonCapturingLambda()) l;
+ int i;
+
+ bool operator==(const TriviallyEqualityComparableContainsLambda&) const = default;
+};
+static_assert(!__is_trivially_equality_comparable(decltype(GetNonCapturingLambda()))); // padding
+static_assert(__is_trivially_equality_comparable(TriviallyEqualityComparableContainsLambda));
+
struct TriviallyEqualityComparableNonTriviallyCopyable {
TriviallyEqualityComparableNonTriviallyCopyable(const TriviallyEqualityComparableNonTriviallyCopyable&);
~TriviallyEqualityComparableNonTriviallyCopyable();
More information about the cfe-commits
mailing list