mizvekov created this revision.
Herald added subscribers: manas, steakhal, ASDenysPetrov, dkrupp, donat.nagy, 
Szelethus, a.sidorin, baloghadamsoftware.
mizvekov requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
This implements a more comprehensive fix than was done at D95409 
<https://reviews.llvm.org/D95409>.
Instead of excluding just function pointer subobjects, we also
exclude any user-defined function pointer conversion operators.

Signed-off-by: Matheus Izvekov <mizve...@gmail.com>

Depends on D103850 <https://reviews.llvm.org/D103850>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D103855

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CXX/class/class.compare/class.spaceship/p2.cpp

Index: clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
===================================================================
--- clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
+++ clang/test/CXX/class/class.compare/class.spaceship/p2.cpp
@@ -197,8 +197,7 @@
     operator fp() const;
   };
   struct b3 {
-    auto operator<=>(b3 const &) const = default; // expected-error {{cannot be deduced because three-way comparison for member 'f' would compare as builtin type 'void (*)()' which is not currently supported}}
-    // expected-warning@-1 {{implicitly deleted}}
-    a3 f;
+    auto operator<=>(b3 const &) const = default; // expected-warning {{implicitly deleted}}
+    a3 f; // expected-note {{because there is no viable three-way comparison function for member 'f'}}
   };
 }
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -7834,10 +7834,10 @@
       SemaRef(SemaRef),
       Context(SemaRef.Context) { }
 
-  void AddTypesConvertedFrom(QualType Ty,
-                             SourceLocation Loc,
+  void AddTypesConvertedFrom(QualType Ty, SourceLocation Loc,
                              bool AllowUserConversions,
                              bool AllowExplicitConversions,
+                             bool DisallowNonRelationalComparableTypes,
                              const Qualifiers &VisibleTypeConversionsQuals);
 
   llvm::iterator_range<iterator> pointer_types() { return PointerTypes; }
@@ -7974,15 +7974,14 @@
 /// primarily interested in pointer types and enumeration types. We also
 /// take member pointer types, for the conditional operator.
 /// AllowUserConversions is true if we should look at the conversion
-/// functions of a class type, and AllowExplicitConversions if we
+/// functions of a class type, AllowExplicitConversions if we
 /// should also include the explicit conversion functions of a class
-/// type.
-void
-BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
-                                               SourceLocation Loc,
-                                               bool AllowUserConversions,
-                                               bool AllowExplicitConversions,
-                                               const Qualifiers &VisibleQuals) {
+/// type, and DisallowNonRelationalComparableTypes if we should exclude types
+/// which cannot be compared with relational operators.
+void BuiltinCandidateTypeSet::AddTypesConvertedFrom(
+    QualType Ty, SourceLocation Loc, bool AllowUserConversions,
+    bool AllowExplicitConversions, bool DisallowNonRelationalComparableTypes,
+    const Qualifiers &VisibleQuals) {
   // Only deal with canonical types.
   Ty = Context.getCanonicalType(Ty);
 
@@ -8009,6 +8008,10 @@
   if (Ty->isObjCIdType() || Ty->isObjCClassType())
     PointerTypes.insert(Ty);
   else if (Ty->getAs<PointerType>() || Ty->getAs<ObjCObjectPointerType>()) {
+    // The builtin operator for relational comparisons on function pointers
+    // is the only known case which cannot be used for three-way comparisons.
+    if (DisallowNonRelationalComparableTypes && Ty->isFunctionPointerType())
+      return;
     // Insert our type, and its more-qualified variants, into the set
     // of types.
     if (!AddPointerWithMoreQualifiedTypeVariants(Ty, VisibleQuals))
@@ -8050,6 +8053,7 @@
       CXXConversionDecl *Conv = cast<CXXConversionDecl>(D);
       if (AllowExplicitConversions || !Conv->isExplicit()) {
         AddTypesConvertedFrom(Conv->getConversionType(), Loc, false, false,
+                              DisallowNonRelationalComparableTypes,
                               VisibleQuals);
       }
     }
@@ -9132,13 +9136,10 @@
   SmallVector<BuiltinCandidateTypeSet, 2> CandidateTypes;
   for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) {
     CandidateTypes.emplace_back(*this);
-    CandidateTypes[ArgIdx].AddTypesConvertedFrom(Args[ArgIdx]->getType(),
-                                                 OpLoc,
-                                                 true,
-                                                 (Op == OO_Exclaim ||
-                                                  Op == OO_AmpAmp ||
-                                                  Op == OO_PipePipe),
-                                                 VisibleTypeConversionsQuals);
+    CandidateTypes[ArgIdx].AddTypesConvertedFrom(
+        Args[ArgIdx]->getType(), OpLoc, true,
+        (Op == OO_Exclaim || Op == OO_AmpAmp || Op == OO_PipePipe),
+        (Op == OO_Less || Op == OO_Spaceship), VisibleTypeConversionsQuals);
     HasNonRecordCandidateType = HasNonRecordCandidateType ||
         CandidateTypes[ArgIdx].hasNonRecordTypes();
     HasArithmeticOrEnumeralCandidateType =
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -7747,16 +7747,11 @@
 
     if (Args[0]->getType()->isOverloadableType())
       S.LookupOverloadedBinOp(CandidateSet, OO, Fns, Args);
-    else if (OO == OO_EqualEqual ||
-             !Args[0]->getType()->isFunctionPointerType()) {
+    else
       // FIXME: We determine whether this is a valid expression by checking to
       // see if there's a viable builtin operator candidate for it. That isn't
       // really what the rules ask us to do, but should give the right results.
-      //
-      // Note that the builtin operator for relational comparisons on function
-      // pointers is the only known case which cannot be used.
       S.AddBuiltinOperatorCandidates(OO, FD->getLocation(), Args, CandidateSet);
-    }
 
     Result R;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D103855: ... Matheus Izvekov via Phabricator via cfe-commits

Reply via email to