diff options
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 12 | ||||
| -rw-r--r-- | clang/test/SemaCXX/overloaded-operator.cpp | 28 | 
2 files changed, 35 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 04bc6b10c0d..daf5b7f3600 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -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. diff --git a/clang/test/SemaCXX/overloaded-operator.cpp b/clang/test/SemaCXX/overloaded-operator.cpp index 5fdbeebdfd1..16d37040f14 100644 --- a/clang/test/SemaCXX/overloaded-operator.cpp +++ b/clang/test/SemaCXX/overloaded-operator.cpp @@ -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; +  } +}  | 

