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 // FIXME: the recovery here is really bad.
102 namespace test1 {
103   template<typename T> class A : public unknown::X { // expected-error {{undeclared identifier 'unknown'}} expected-error {{expected class name}}
104     A(UndeclaredType n) : X(n) {} // expected-error{{expected ')'}} expected-note{{to match this '('}} \
105     // expected-error{{use of undeclared identifier 'n'}} \
106     // expected-error{{expected ';' at end of declaration list}} \
107     // expected-error{{field has incomplete type 'test1::A<char>'}}
108   };
109   template<typename T> class B : public A<T>     {
110     virtual void foo() {}
111   };
112   extern template class A<char>; // expected-note {{in instantiation of template class 'test1::A<char>' requested here}} \
113                                  // expected-note {{definition of 'test1::A<char>' is not complete until the closing '}'}}
114   extern template class B<char>;
115 }
116