Home | History | Annotate | Download | only in SemaCXX
      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