https://github.com/AMP999 updated https://github.com/llvm/llvm-project/pull/68506
>From fdbeba9c94ddb13ee53a761d9e1a95b044f2c20a Mon Sep 17 00:00:00 2001 From: Amirreza Ashouri <ar.ashouri...@gmail.com> Date: Sat, 7 Oct 2023 19:02:34 +0330 Subject: [PATCH 1/3] [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 5820c4e478c035a65512994f354df081266467dc Mon Sep 17 00:00:00 2001 From: Amirreza Ashouri <ar.ashouri...@gmail.com> Date: Sun, 8 Oct 2023 18:00:51 +0330 Subject: [PATCH 2/3] [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 | 3 +++ clang/test/SemaCXX/type-traits.cpp | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 4c433f7fe9daca0..23f856c715a5e13 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2663,6 +2663,9 @@ 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(); >From e7a5141ca78d0182cf3a372838bdc40b209e56b1 Mon Sep 17 00:00:00 2001 From: Arthur O'Dwyer <arthur.j.odw...@gmail.com> Date: Tue, 10 Oct 2023 10:03:17 -0400 Subject: [PATCH 3/3] [clang] Factor out isCapturelessLambda This changes the behavior of the call-site in "CodeGenFunction.cpp", I think for the better. But I couldn't figure out how to test that codepath. --- clang/include/clang/AST/DeclCXX.h | 6 ++++++ clang/lib/AST/DeclCXX.cpp | 2 +- clang/lib/AST/Type.cpp | 3 +-- clang/lib/CodeGen/CodeGenFunction.cpp | 4 ++-- clang/lib/Sema/SemaLambda.cpp | 3 +-- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index aa3e3322faa42e3..5eaae6bdd2bc63e 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1052,6 +1052,12 @@ class CXXRecordDecl : public RecordDecl { return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault); } + bool isCapturelessLambda() const { + if (!isLambda()) + return false; + return getLambdaCaptureDefault() == LCD_None && capture_size() == 0; + } + /// Set the captures for this lambda closure type. void setCaptures(ASTContext &Context, ArrayRef<LambdaCapture> Captures); diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index a92b788366434ce..9107525a44f22c2 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -686,7 +686,7 @@ bool CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable() const { // C++17 [expr.prim.lambda]p21: // The closure type associated with a lambda-expression has no default // constructor and a deleted copy assignment operator. - if (getLambdaCaptureDefault() != LCD_None || capture_size() != 0) + if (!isCapturelessLambda()) return false; return getASTContext().getLangOpts().CPlusPlus20; } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 23f856c715a5e13..282298971705ba0 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2664,8 +2664,7 @@ HasNonDeletedDefaultedEqualityComparison(const CXXRecordDecl *Decl) { if (Decl->isUnion()) return false; if (Decl->isLambda()) - return Decl->captures().empty() && - (Decl->getLambdaCaptureDefault() == LCD_None); + return Decl->isCapturelessLambda(); auto IsDefaultedOperatorEqualEqual = [&](const FunctionDecl *Function) { return Function->getOverloadedOperator() == diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 9b21f428b0af7f5..280fd716db2b2ec 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1216,11 +1216,11 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, SkippedChecks.set(SanitizerKind::ObjectSize, true); QualType ThisTy = MD->getThisType(); - // If this is the call operator of a lambda with no capture-default, it + // If this is the call operator of a lambda with no captures, it // may have a static invoker function, which may call this operator with // a null 'this' pointer. if (isLambdaCallOperator(MD) && - MD->getParent()->getLambdaCaptureDefault() == LCD_None) + MD->getParent()->isCapturelessLambda()) SkippedChecks.set(SanitizerKind::Null, true); EmitTypeCheck( diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 421048aaff5c90c..ca09b0481bcac76 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -393,8 +393,7 @@ void Sema::DiagnoseInvalidExplicitObjectParameterInLambda( CXXRecordDecl *RD = Method->getParent(); if (Method->getType()->isDependentType()) return; - if (RD->getLambdaCaptureDefault() == LambdaCaptureDefault::LCD_None && - RD->capture_size() == 0) + if (RD->isCapturelessLambda()) return; QualType ExplicitObjectParameterType = Method->getParamDecl(0) ->getType() _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits