Author: rsmith
Date: Tue Sep 23 15:31:39 2014
New Revision: 218330

URL: http://llvm.org/viewvc/llvm-project?rev=218330&view=rev
Log:
Don't perform ADL when looking up operator=; there is no non-member form of
that function, and apart from being slow, this is unnecessary: ADL can trigger
instantiations that are not permitted here. The standard isn't *completely*
clear here, but this seems like the intent, and in any case this approach is
permitted by [temp.inst]p7.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/CXX/drs/dr2xx.cpp
    cfe/trunk/test/SemaCXX/overloaded-operator.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=218330&r1=218329&r2=218330&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Sep 23 15:31:39 2014
@@ -9704,7 +9704,7 @@ static ExprResult BuildOverloadedBinOp(S
   UnresolvedSet<16> Functions;
   OverloadedOperatorKind OverOp
     = BinaryOperator::getOverloadedOperator(Opc);
-  if (Sc && OverOp != OO_None)
+  if (Sc && OverOp != OO_None && OverOp != OO_Equal)
     S.LookupOverloadedOperatorName(OverOp, Sc, LHS->getType(),
                                    RHS->getType(), Functions);
 

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=218330&r1=218329&r2=218330&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Sep 23 15:31:39 2014
@@ -11031,10 +11031,13 @@ Sema::CreateOverloadedBinOp(SourceLocati
   // Add operator candidates that are member functions.
   AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet);
 
-  // Add candidates from ADL.
-  AddArgumentDependentLookupCandidates(OpName, OpLoc, Args,
-                                       /*ExplicitTemplateArgs*/ nullptr,
-                                       CandidateSet);
+  // Add candidates from ADL. Per [over.match.oper]p2, this lookup is not
+  // performed for an assignment operator (nor for operator[] nor operator->,
+  // which don't get here).
+  if (Opc != BO_Assign)
+    AddArgumentDependentLookupCandidates(OpName, OpLoc, Args,
+                                         /*ExplicitTemplateArgs*/ nullptr,
+                                         CandidateSet);
 
   // Add builtin operator candidates.
   AddBuiltinOperatorCandidates(Op, OpLoc, Args, CandidateSet);

Modified: cfe/trunk/test/CXX/drs/dr2xx.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr2xx.cpp?rev=218330&r1=218329&r2=218330&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr2xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr2xx.cpp Tue Sep 23 15:31:39 2014
@@ -195,8 +195,8 @@ namespace dr218 { // dr218: yes
 // dr220: na
 
 namespace dr221 { // dr221: yes
-  struct A {
-    A &operator=(int&);
+  struct A { // expected-note 2-4{{candidate}}
+    A &operator=(int&); // expected-note 2{{candidate}}
     A &operator+=(int&);
     static A &operator=(A&, double&); // expected-error {{cannot be a static 
member}}
     static A &operator+=(A&, double&); // expected-error {{cannot be a static 
member}}
@@ -209,9 +209,9 @@ namespace dr221 { // dr221: yes
   void test(A a, int n, char c, float f) {
     a = n;
     a += n;
-    a = c;
+    a = c; // expected-error {{no viable}}
     a += c;
-    a = f;
+    a = f; // expected-error {{no viable}}
     a += f;
   }
 }

Modified: cfe/trunk/test/SemaCXX/overloaded-operator.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overloaded-operator.cpp?rev=218330&r1=218329&r2=218330&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/overloaded-operator.cpp (original)
+++ cfe/trunk/test/SemaCXX/overloaded-operator.cpp Tue Sep 23 15:31:39 2014
@@ -519,3 +519,15 @@ namespace ConversionVersusTemplateOrderi
   int x = a;
   int y = b;
 }
+
+namespace NoADLForMemberOnlyOperators {
+  template<typename T> struct A { typename T::error e; }; // expected-error 
{{type 'char' cannot be used prior to '::'}}
+  template<typename T> struct B { int n; };
+
+  void f(B<A<void> > b1, B<A<int> > b2, B<A<char> > b3) {
+    b1 = b1; // ok, does not instantiate A<void>.
+    (void)b1->n; // expected-error {{is not a pointer}}
+    b2[3]; // expected-error {{does not provide a subscript}}
+    b3 / 0; // expected-note {{in instantiation of}} expected-error {{invalid 
operands to}}
+  }
+}


_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to