Daniel Dunbar | 8fbe78f | 2009-12-15 20:14:24 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -fsyntax-only -verify %s |
Charles Li | 542f04c | 2015-11-11 19:34:47 +0000 | [diff] [blame] | 2 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s |
| 3 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s |
| 4 | |
Douglas Gregor | 6bd18af | 2009-01-16 03:02:29 +0000 | [diff] [blame] | 5 | struct ConvToBool { |
| 6 | operator bool() const; |
| 7 | }; |
| 8 | |
| 9 | struct ConvToInt { |
| 10 | operator int(); |
| 11 | }; |
| 12 | |
| 13 | struct ExplicitConvToBool { |
Charles Li | 542f04c | 2015-11-11 19:34:47 +0000 | [diff] [blame] | 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 |
Douglas Gregor | 6bd18af | 2009-01-16 03:02:29 +0000 | [diff] [blame] | 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 | |
Douglas Gregor | e254f90 | 2009-02-04 00:32:51 +0000 | [diff] [blame] | 45 | void accepts_bool(bool) { } // expected-note{{candidate function}} |
Douglas Gregor | 6bd18af | 2009-01-16 03:02:29 +0000 | [diff] [blame] | 46 | |
| 47 | struct ExplicitConvToRef { |
Charles Li | 542f04c | 2015-11-11 19:34:47 +0000 | [diff] [blame] | 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 |
Douglas Gregor | 6bd18af | 2009-01-16 03:02:29 +0000 | [diff] [blame] | 52 | }; |
| 53 | |
| 54 | void test_explicit_bool(ExplicitConvToBool ecb) { |
| 55 | bool b1(ecb); // okay |
John McCall | 85f9055 | 2010-03-10 11:27:22 +0000 | [diff] [blame] | 56 | bool b2 = ecb; // expected-error{{no viable conversion from 'ExplicitConvToBool' to 'bool'}} |
Douglas Gregor | e254f90 | 2009-02-04 00:32:51 +0000 | [diff] [blame] | 57 | accepts_bool(ecb); // expected-error{{no matching function for call to}} |
Douglas Gregor | 6bd18af | 2009-01-16 03:02:29 +0000 | [diff] [blame] | 58 | } |
| 59 | |
| 60 | void test_explicit_conv_to_ref(ExplicitConvToRef ecr) { |
John McCall | 85f9055 | 2010-03-10 11:27:22 +0000 | [diff] [blame] | 61 | int& i1 = ecr; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'ExplicitConvToRef'}} |
Douglas Gregor | 6bd18af | 2009-01-16 03:02:29 +0000 | [diff] [blame] | 62 | int& i2(ecr); // okay |
| 63 | } |
| 64 | |
| 65 | struct A { }; |
| 66 | struct B { }; |
| 67 | struct C { |
Charles Li | 542f04c | 2015-11-11 19:34:47 +0000 | [diff] [blame] | 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 |
Douglas Gregor | 3e1e527 | 2009-12-09 23:02:17 +0000 | [diff] [blame] | 72 | operator B&(); // expected-note{{candidate}} |
Douglas Gregor | 6bd18af | 2009-01-16 03:02:29 +0000 | [diff] [blame] | 73 | }; |
| 74 | |
| 75 | void test_copy_init_conversions(C c) { |
John McCall | 85f9055 | 2010-03-10 11:27:22 +0000 | [diff] [blame] | 76 | A &a = c; // expected-error{{no viable conversion from 'C' to 'A'}} |
Hans Wennborg | e1fdb05 | 2012-08-17 10:12:33 +0000 | [diff] [blame] | 77 | B &b = c; // okay |
Douglas Gregor | 6bd18af | 2009-01-16 03:02:29 +0000 | [diff] [blame] | 78 | } |