1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
3 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
4 
5 struct ConvToBool {
6   operator bool() const;
7 };
8 
9 struct ConvToInt {
10   operator int();
11 };
12 
13 struct ExplicitConvToBool {
14   explicit operator bool(); // expected-note {{explicit}}
15 #if __cplusplus <= 199711L // C++03 or earlier modes
16   // expected-warning@-2{{explicit conversion functions are a C++11 extension}}
17 #endif
18 };
19 
test_conv_to_bool(ConvToBool ctb,ConvToInt cti,ExplicitConvToBool ecb)20 void test_conv_to_bool(ConvToBool ctb, ConvToInt cti, ExplicitConvToBool ecb) {
21   if (ctb) { }
22   if (cti) { }
23   if (ecb) { }
24   for (; ctb; ) { }
25   for (; cti; ) { }
26   for (; ecb; ) { }
27   while (ctb) { };
28   while (cti) { }
29   while (ecb) { }
30   do { } while (ctb);
31   do { } while (cti);
32   do { } while (ecb);
33 
34   if (!ctb) { }
35   if (!cti) { }
36   if (!ecb) { }
37 
38   bool b1 = !ecb;
39   if (ctb && ecb) { }
40   bool b2 = ctb && ecb;
41   if (ctb || ecb) { }
42   bool b3 = ctb || ecb;
43 }
44 
accepts_bool(bool)45 void accepts_bool(bool) { } // expected-note{{candidate function}}
46 
47 struct ExplicitConvToRef {
48   explicit operator int&(); // expected-note {{explicit}}
49 #if (__cplusplus <= 199711L) // C++03 or earlier modes
50   // expected-warning@-2{{explicit conversion functions are a C++11 extension}}
51 #endif
52 };
53 
test_explicit_bool(ExplicitConvToBool ecb)54 void test_explicit_bool(ExplicitConvToBool ecb) {
55   bool b1(ecb); // okay
56   bool b2 = ecb; // expected-error{{no viable conversion from 'ExplicitConvToBool' to 'bool'}}
57   accepts_bool(ecb); // expected-error{{no matching function for call to}}
58 }
59 
test_explicit_conv_to_ref(ExplicitConvToRef ecr)60 void test_explicit_conv_to_ref(ExplicitConvToRef ecr) {
61   int& i1 = ecr; // expected-error{{no viable conversion from 'ExplicitConvToRef' to 'int'}}
62   int& i2(ecr); // okay
63 }
64 
65 struct A { };
66 struct B { };
67 struct C {
68   explicit operator A&();  // expected-note {{explicit}}
69 #if __cplusplus <= 199711L // C++03 or earlier modes
70 // expected-warning@-2{{explicit conversion functions are a C++11 extension}}
71 #endif
72   operator B&(); // expected-note{{candidate}}
73 };
74 
test_copy_init_conversions(C c)75 void test_copy_init_conversions(C c) {
76   A &a = c; // expected-error{{no viable conversion from 'C' to 'A'}}
77   B &b = c; // okay
78 }
79