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(); |
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 | |
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 | |
45 | void accepts_bool(bool) { } // expected-note{{candidate function}} |
46 | |
47 | struct ExplicitConvToRef { |
48 | explicit operator int&(); |
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 | |
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 | |
60 | void test_explicit_conv_to_ref(ExplicitConvToRef ecr) { |
61 | int& i1 = ecr; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'ExplicitConvToRef'}} |
62 | int& i2(ecr); // okay |
63 | } |
64 | |
65 | struct A { }; |
66 | struct B { }; |
67 | struct C { |
68 | explicit operator A&(); |
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 | |
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 | |