]> granicus.if.org Git - clang/commitdiff
Fix overload resolution between Ptr-To-Member and Bool
authorErich Keane <erich.keane@intel.com>
Tue, 12 Jun 2018 13:59:32 +0000 (13:59 +0000)
committerErich Keane <erich.keane@intel.com>
Tue, 12 Jun 2018 13:59:32 +0000 (13:59 +0000)
As reported here (https://bugs.llvm.org/show_bug.cgi?id=19808)
and discovered independently when looking at plum-hall tests,
we incorrectly implemented over.ics.rank, which says "A conversion
that is not a conversion of a pointer, or pointer to member, to bool
is better than another conversion that is such a conversion.".

In the current Draft (N4750), this is phrased slightly differently in
paragraph 4.1: A conversion that does not convert a pointer, a pointer
to member, or std::nullptr_t to bool is better than one that does.

The comment on isPointerConversionToBool (the changed function)
also confirms that this is the case (note outdated reference):
isPointerConversionToBool - Determines whether this conversion is
a conversion of a pointer or pointer-to-member to bool. This is
used as part of the ranking of standard conversion sequences
(C++ 13.3.3.2p4).

However, despite this comment, it didn't check isMemberPointerType
on the 'FromType', presumably incorrectly assuming that 'isPointerType'
matched it.  This patch fixes this by adding isMemberPointerType to
this function. Additionally, member function pointers are just
MemberPointerTypes that point to functions insted of data, so that
is fixed in this patch as well.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@334503 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOverload.cpp
test/SemaCXX/overload-call.cpp

index 5e74b54331fae52bb6f32855062628fa15122935..45639a718caf90878af3741065c04e14852686b1 100644 (file)
@@ -223,6 +223,7 @@ bool StandardConversionSequence::isPointerConversionToBool() const {
   // a pointer.
   if (getToType(1)->isBooleanType() &&
       (getFromType()->isPointerType() ||
+       getFromType()->isMemberPointerType() ||
        getFromType()->isObjCObjectPointerType() ||
        getFromType()->isBlockPointerType() ||
        getFromType()->isNullPtrType() ||
index 25c619b242e4ece895a91b7e7ea636cad2971031..befa927f06778ce04ed9e35c365f880a41616a69 100644 (file)
@@ -667,3 +667,24 @@ namespace ProduceNotesAfterSFINAEFailure {
   void f(void*, A); // expected-note {{candidate function not viable}}
   void g() { f(1, 2); } // expected-error {{no matching function}}
 }
+
+namespace PR19808 {
+  struct B {
+    int i;
+    void bar();
+  };
+  struct D : public B{};
+
+  void f(bool);
+  void f(int D::*);
+  void f(void (D::*)());
+
+  void Usage() {
+    int B::*pmem;
+    void (B::*pmf)();
+
+    // These should not be ambiguous.
+    f(pmem);
+    f(pmf);
+  }
+}