1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s 2 namespace Constructor { 3 struct A { 4 A(int); 5 }; 6 7 struct B { 8 explicit B(int); 9 }; 10 11 B::B(int) { } 12 13 struct C { 14 void f(const A&); 15 void f(const B&); 16 }; 17 18 void f(C c) { 19 c.f(10); 20 } 21 } 22 23 namespace Conversion { 24 struct A { 25 operator int(); 26 explicit operator bool(); 27 }; 28 29 A::operator bool() { return false; } 30 31 struct B { 32 void f(int); 33 void f(bool); 34 }; 35 36 void f(A a, B b) { 37 b.f(a); 38 } 39 40 void testExplicit() 41 { 42 // Taken from 12.3.2p2 43 class Y { }; // expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y &' for 1st argument}} \ 44 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y &&' for 1st argument}} \ 45 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y &' for 1st argument}} \ 46 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \ 47 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \ 48 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \ 49 expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} \ 50 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \ 51 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \ 52 expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} \ 53 expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \ 54 expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y &&' for 1st argument}} \ 55 expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} 56 struct Z { 57 explicit operator Y() const; 58 explicit operator int() const; 59 }; 60 61 Z z; 62 // 13.3.1.4p1 & 8.5p16: 63 Y y2 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'Conversion::Y'}} 64 // FIXME: These are well-formed per C++0x 13.3.1.4p1 (see DR899). 65 Y y3 = (Y)z; // expected-error {{no matching conversion for C-style cast from 'Conversion::Z' to 'Conversion::Y''}} 66 Y y4 = Y(z); // expected-error {{no matching conversion for functional-style cast from 'Conversion::Z' to 'Conversion::Y'}} 67 Y y5 = static_cast<Y>(z); // expected-error {{no matching conversion for static_cast from 'Conversion::Z' to 'Conversion::Y'}} 68 // 13.3.1.5p1 & 8.5p16: 69 int i1 = (int)z; 70 int i2 = int(z); 71 int i3 = static_cast<int>(z); 72 int i4(z); 73 // 13.3.1.6p1 & 8.5.3p5: 74 const Y& y6 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'const Conversion::Y'}} 75 const int& y7(z); 76 } 77 78 void testBool() { 79 struct Bool { 80 operator bool(); 81 }; 82 83 struct NotBool { 84 explicit operator bool(); // expected-note {{conversion to integral type 'bool'}} 85 }; 86 Bool b; 87 NotBool n; 88 89 (void) (1 + b); 90 (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'Conversion::NotBool')}} 91 92 // 5.3.1p9: 93 (void) (!b); 94 (void) (!n); 95 96 // 5.14p1: 97 (void) (b && true); 98 (void) (n && true); 99 100 // 5.15p1: 101 (void) (b || true); 102 (void) (n || true); 103 104 // 5.16p1: 105 (void) (b ? 0 : 1); 106 (void) (n ? 0: 1); 107 108 // 5.19p5: 109 // TODO: After constexpr has been implemented 110 111 // 6.4p4: 112 if (b) {} 113 if (n) {} 114 115 // 6.4.2p2: 116 switch (b) {} // expected-warning {{switch condition has boolean value}} 117 switch (n) {} // expected-error {{switch condition type 'Conversion::NotBool' requires explicit conversion to 'bool'}} \ 118 expected-warning {{switch condition has boolean value}} 119 120 // 6.5.1: 121 while (b) {} 122 while (n) {} 123 124 // 6.5.2p1: 125 do {} while (b); 126 do {} while (n); 127 128 // 6.5.3: 129 for (;b;) {} 130 for (;n;) {} 131 } 132 133 void testNew() 134 { 135 // 5.3.4p6: 136 struct Int { 137 operator int(); 138 }; 139 struct NotInt { 140 explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}} 141 }; 142 143 Int i; 144 NotInt ni; 145 146 new int[i]; 147 new int[ni]; // expected-error {{array size expression of type 'Conversion::NotInt' requires explicit conversion to type 'int'}} 148 } 149 150 void testDelete() 151 { 152 // 5.3.5pp2: 153 struct Ptr { 154 operator int*(); 155 }; 156 struct NotPtr { 157 explicit operator int*(); 158 }; 159 160 Ptr p; 161 NotPtr np; 162 163 delete p; 164 delete np; // expected-error {{cannot delete expression of type 'Conversion::NotPtr'}} 165 } 166 167 void testFunctionPointer() 168 { 169 // 13.3.1.1.2p2: 170 using Func = void(*)(int); 171 172 struct FP { 173 operator Func(); 174 }; 175 struct NotFP { 176 explicit operator Func(); 177 }; 178 179 FP fp; 180 NotFP nfp; 181 fp(1); 182 nfp(1); // expected-error {{type 'Conversion::NotFP' does not provide a call operator}} 183 } 184 } 185