]> granicus.if.org Git - clang/commitdiff
Do overload resolution for compound assignment even if only the RHS is overloadable...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Wed, 18 Nov 2009 23:10:33 +0000 (23:10 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Wed, 18 Nov 2009 23:10:33 +0000 (23:10 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89268 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOverload.cpp
test/SemaCXX/overloaded-operator.cpp

index 04bc6b10c0d7368f633d53b1c98d299520c7b101..daf5b7f36008e34363709a4057480241ed733bcb 100644 (file)
@@ -4895,11 +4895,13 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
   if (Opc == BinaryOperator::PtrMemD)
     return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 
-  // If this is one of the assignment operators, we only perform
-  // overload resolution if the left-hand side is a class or
-  // enumeration type (C++ [expr.ass]p3).
-  if (Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign &&
-      !Args[0]->getType()->isOverloadableType())
+  // If this is the assignment operator, we only perform overload resolution
+  // if the left-hand side is a class or enumeration type. This is actually
+  // a hack. The standard requires that we do overload resolution between the
+  // various built-in candidates, but as DR507 points out, this can lead to
+  // problems. So we do it this way, which pretty much follows what GCC does.
+  // Note that we go the traditional code path for compound assignment forms.
+  if (Opc==BinaryOperator::Assign && !Args[0]->getType()->isOverloadableType())
     return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 
   // Build an empty overload set.
index 5fdbeebdfd1ffbd96abd029a7ff6b4759a6b85ea..16d37040f140542dc7361bd619bf9e77e9f0d13f 100644 (file)
@@ -296,3 +296,31 @@ namespace pr5546
   const char* a() { return sMoveCommands[X][0][0]; }
   const char* b() { return (*(sMoveCommands+X))[0][0]; }
 }
+
+// PR5512 and its discussion
+namespace pr5512 {
+  struct Y {
+    operator short();
+    operator float();
+  };
+  void g_test(Y y) {
+    short s = 0;
+    // DR507, this should be ambiguous, but we special-case assignment
+    s = y;
+    // Note: DR507, this is ambiguous as specified
+    //s += y;
+  }
+
+  struct S {};
+  void operator +=(int&, S);
+  void f(S s) {
+    int i = 0;
+    i += s;
+  }
+
+  struct A {operator int();};
+  int a;
+  void b(A x) {
+    a += x;
+  }
+}