1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 struct A {
3 };
4 
5 struct ConvertibleToA {
6   operator A();
7 };
8 
9 struct ConvertibleToConstA {
10   operator const A();
11 };
12 
13 struct B {
14   B& operator=(B&);  // expected-note 4 {{candidate function}}
15 };
16 
17 struct ConvertibleToB {
18   operator B();
19 };
20 
21 struct ConvertibleToBref {
22   operator B&();
23 };
24 
25 struct ConvertibleToConstB {
26   operator const B();
27 };
28 
29 struct ConvertibleToConstBref {
30   operator const B&();
31 };
32 
33 struct C {
34   int operator=(int); // expected-note{{candidate function}}
35   long operator=(long); // expected-note{{candidate function}}
36   int operator+=(int); // expected-note{{candidate function}}
37   int operator+=(long); // expected-note{{candidate function}}
38 };
39 
40 struct D {
41   D& operator+=(const D &);
42 };
43 
44 struct ConvertibleToInt {
45   operator int();
46 };
47 
48 void test() {
49   A a, na;
50   const A constA = A();
51   ConvertibleToA convertibleToA;
52   ConvertibleToConstA convertibleToConstA;
53 
54   B b, nb;
55   const B constB = B();
56   ConvertibleToB convertibleToB;
57   ConvertibleToBref convertibleToBref;
58   ConvertibleToConstB convertibleToConstB;
59   ConvertibleToConstBref convertibleToConstBref;
60 
61   C c, nc;
62   const C constC = C();
63 
64   D d, nd;
65   const D constD = D();
66 
67   ConvertibleToInt convertibleToInt;
68 
69   na = a;
70   na = constA;
71   na = convertibleToA;
72   na = convertibleToConstA;
73   na += a; // expected-error{{no viable overloaded '+='}}
74 
75   nb = b;
76   nb = constB;  // expected-error{{no viable overloaded '='}}
77   nb = convertibleToB; // expected-error{{no viable overloaded '='}}
78   nb = convertibleToBref;
79   nb = convertibleToConstB; // expected-error{{no viable overloaded '='}}
80   nb = convertibleToConstBref; // expected-error{{no viable overloaded '='}}
81 
82   nc = c;
83   nc = constC;
84   nc = 1;
85   nc = 1L;
86   nc = 1.0; // expected-error{{use of overloaded operator '=' is ambiguous}}
87   nc += 1;
88   nc += 1L;
89   nc += 1.0; // expected-error{{use of overloaded operator '+=' is ambiguous}}
90 
91   nd = d;
92   nd += d;
93   nd += constD;
94 
95   int i;
96   i = convertibleToInt;
97   i = a; // expected-error{{assigning to 'int' from incompatible type 'A'}}
98 }
99 
100 // <rdar://problem/8315440>: Don't crash
101 namespace test1 {
102   template<typename T> class A : public unknown::X { // expected-error {{undeclared identifier 'unknown'}} expected-error {{expected class name}}
103     A(UndeclaredType n) : X(n) {} // expected-error {{unknown type name 'UndeclaredType'}}
104   };
105   template<typename T> class B : public A<T>     {
106     virtual void foo() {}
107   };
108   extern template class A<char>;
109   extern template class B<char>;
110 }
111