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; + } +} |