[cfe-commits] r124216 - in /cfe/trunk: lib/Sema/SemaOverload.cpp test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp

Douglas Gregor dgregor at apple.com
Tue Jan 25 11:39:31 PST 2011


Author: dgregor
Date: Tue Jan 25 13:39:31 2011
New Revision: 124216

URL: http://llvm.org/viewvc/llvm-project?rev=124216&view=rev
Log:
Fix the ranking of reference bindings during overload resolution
(C++0x [over.ics.rank]p3) when one binding is an lvalue reference and
the other is an rvalue reference that binds to an rvalue. In
particular, we were using the predict "is an rvalue reference" rather
than "is an rvalue reference that binds to an rvalue", which was
incorrect in the one case where an rvalue reference can bind to an
lvalue: function references.

This particular issue cropped up with std::forward, where Clang was
picking an std::forward overload while forwarding an (lvalue)
reference to a function. However (and unfortunately!), the right
answer for this code is that the call to std::forward is
ambiguous. Clang now gets that right, but we need to revisit the
std::forward implementation in libc++.

Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=124216&r1=124215&r2=124216&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Jan 25 13:39:31 2011
@@ -2966,7 +2966,7 @@
       ICS.Standard.setToType(2, T1);
       ICS.Standard.ReferenceBinding = true;
       ICS.Standard.DirectBinding = true;
-      ICS.Standard.RRefBinding = isRValRef;
+      ICS.Standard.RRefBinding = isRValRef && InitCategory.isRValue();
       ICS.Standard.CopyConstructor = 0;
 
       // Nothing more to do: the inaccessibility/ambiguity check for
@@ -3036,7 +3036,7 @@
     ICS.Standard.DirectBinding = 
       S.getLangOptions().CPlusPlus0x || 
       (InitCategory.isPRValue() && !T2->isRecordType());
-    ICS.Standard.RRefBinding = isRValRef;
+    ICS.Standard.RRefBinding = isRValRef && InitCategory.isRValue();
     ICS.Standard.CopyConstructor = 0;
     return ICS; 
   }

Modified: cfe/trunk/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp?rev=124216&r1=124215&r2=124216&view=diff
==============================================================================
--- cfe/trunk/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp (original)
+++ cfe/trunk/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp Tue Jan 25 13:39:31 2011
@@ -15,7 +15,7 @@
   float &k2 = g2(f1());
   float &l2 = g2(f2());
 
-  // FIXME: We don't support ref-qualifiers set.
+  // FIXME: We don't support ref-qualifiers yet.
 #if 0
   struct A { 
     A& operator<<(int); 
@@ -33,3 +33,27 @@
   a.p();
 #endif
 }
+
+template<typename T>
+struct remove_reference {
+  typedef T type;
+};
+
+template<typename T>
+struct remove_reference<T&> {
+  typedef T type;
+};
+
+template<typename T>
+struct remove_reference<T&&> {
+  typedef T type;
+};
+
+namespace FunctionReferencesOverloading {
+  template<typename T> int &f(typename remove_reference<T>::type&); // expected-note{{candidate function [with T = int (&)(int)]}}
+  template<typename T> float &f(typename remove_reference<T>::type&&); // expected-note{{candidate function [with T = int (&)(int)]}}
+
+  void test_f(int (&func_ref)(int)) {
+    f<int (&)(int)>(func_ref); // expected-error{{call to 'f' is ambiguous}}
+  }
+}





More information about the cfe-commits mailing list