diff options
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 9 | ||||
-rw-r--r-- | test/SemaCXX/copy-assignment.cpp | 99 | ||||
-rw-r--r-- | test/SemaCXX/namespace.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/overloaded-builtin-operators.cpp | 2 | ||||
-rw-r--r-- | test/SemaTemplate/qualified-names-diag.cpp | 2 |
5 files changed, 111 insertions, 3 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index ef175315e6..98ee13af85 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -4020,6 +4020,15 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, } case OR_No_Viable_Function: + // For class as left operand for assignment or compound assigment operator + // do not fall through to handling in built-in, but report that no overloaded + // assignment operator found + if (LHS->getType()->isRecordType() && Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign) { + Diag(OpLoc, diag::err_ovl_no_viable_oper) + << BinaryOperator::getOpcodeStr(Opc) + << LHS->getSourceRange() << RHS->getSourceRange(); + return ExprError(); + } // No viable function; fall through to handling this as a // built-in operator, which will produce an error message for us. break; diff --git a/test/SemaCXX/copy-assignment.cpp b/test/SemaCXX/copy-assignment.cpp new file mode 100644 index 0000000000..6e5012f5a7 --- /dev/null +++ b/test/SemaCXX/copy-assignment.cpp @@ -0,0 +1,99 @@ +// RUN: clang-cc -fsyntax-only -verify %s +struct A { +}; + +struct ConvertibleToA { + operator A(); +}; + +struct ConvertibleToConstA { + operator const A(); +}; + +struct B { + B& operator=(B&); +}; + +struct ConvertibleToB { + operator B(); +}; + +struct ConvertibleToBref { + operator B&(); +}; + +struct ConvertibleToConstB { + operator const B(); +}; + +struct ConvertibleToConstBref { + operator const B&(); +}; + +struct C { + int operator=(int); // expected-note{{candidate function}} + long operator=(long); // expected-note{{candidate function}} + int operator+=(int); // expected-note{{candidate function}} + int operator+=(long); // expected-note{{candidate function}} +}; + +struct D { + D& operator+=(const D &); +}; + +struct ConvertibleToInt { + operator int(); +}; + +void test() { + A a, na; + const A constA; + ConvertibleToA convertibleToA; + ConvertibleToConstA convertibleToConstA; + + B b, nb; + const B constB; + ConvertibleToB convertibleToB; + ConvertibleToBref convertibleToBref; + ConvertibleToConstB convertibleToConstB; + ConvertibleToConstBref convertibleToConstBref; + + C c, nc; + const C constC; + + D d, nd; + const D constD; + + ConvertibleToInt convertibleToInt; + + na = a; + na = constA; + na = convertibleToA; + na = convertibleToConstA; + na += a; // expected-error{{no viable overloaded '+='}} + + nb = b; + nb = constB; // expected-error{{no viable overloaded '='}} + nb = convertibleToB; // expected-error{{no viable overloaded '='}} + nb = convertibleToBref; + nb = convertibleToConstB; // expected-error{{no viable overloaded '='}} + nb = convertibleToConstBref; // expected-error{{no viable overloaded '='}} + + nc = c; + nc = constC; + nc = 1; + nc = 1L; + nc = 1.0; // expected-error{{use of overloaded operator '=' is ambiguous}} + nc += 1; + nc += 1L; + nc += 1.0; // expected-error{{use of overloaded operator '+=' is ambiguous}} + + nd = d; + nd += d; + nd += constD; + + int i; + i = convertibleToInt; + i = a; // expected-error{{incompatible type assigning 'struct A', expected 'int'}} +} + diff --git a/test/SemaCXX/namespace.cpp b/test/SemaCXX/namespace.cpp index 592ca30790..696ea818f6 100644 --- a/test/SemaCXX/namespace.cpp +++ b/test/SemaCXX/namespace.cpp @@ -37,7 +37,7 @@ namespace S1 { namespace S3 { void f() { - x = 0; // expected-error {{incompatible type assigning 'int', expected 'class B'}} + x = 0; // expected-error {{no viable overloaded '='}} } } diff --git a/test/SemaCXX/overloaded-builtin-operators.cpp b/test/SemaCXX/overloaded-builtin-operators.cpp index 5989dc2726..2a6c24a677 100644 --- a/test/SemaCXX/overloaded-builtin-operators.cpp +++ b/test/SemaCXX/overloaded-builtin-operators.cpp @@ -118,5 +118,5 @@ void test_with_ptrs(VolatileIntPtr vip, ConstIntPtr cip, ShortRef sr, // C++ [over.match.open]p4 void test_assign_restrictions(ShortRef& sr) { - sr = (short)0; // expected-error{{incompatible type assigning 'short', expected 'struct ShortRef'}} + sr = (short)0; // expected-error{{no viable overloaded '='}} } diff --git a/test/SemaTemplate/qualified-names-diag.cpp b/test/SemaTemplate/qualified-names-diag.cpp index 4bc8bdfc9a..c875332905 100644 --- a/test/SemaTemplate/qualified-names-diag.cpp +++ b/test/SemaTemplate/qualified-names-diag.cpp @@ -12,5 +12,5 @@ void test() { std::vector<INT> v1; vector<Real> v2; - v1 = v2; // expected-error{{incompatible type assigning 'vector<Real>', expected 'std::vector<INT>'}} + v1 = v2; // expected-error{{no viable overloaded '='}} } |