Home | History | Annotate | Download | only in SemaCXX
      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 { // expected-note+ {{candidate}}
      8   explicit B(int);
      9 };
     10 
     11 B::B(int) { } // expected-note+ {{here}}
     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 A a0 = 0;
     23 A a1(0);
     24 A &&a2 = 0;
     25 A &&a3(0);
     26 A a4{0};
     27 A &&a5 = {0};
     28 A &&a6{0};
     29 
     30 B b0 = 0; // expected-error {{no viable conversion}}
     31 B b1(0);
     32 B &&b2 = 0; // expected-error {{could not bind}}
     33 B &&b3(0); // expected-error {{could not bind}}
     34 B b4{0};
     35 B &&b5 = {0}; // expected-error {{chosen constructor is explicit}}
     36 B &&b6{0};
     37 }
     38 
     39 namespace Conversion {
     40   struct A {
     41     operator int();
     42     explicit operator bool();
     43   };
     44 
     45   A::operator bool() { return false; }
     46 
     47   struct B {
     48     void f(int);
     49     void f(bool);
     50   };
     51 
     52   void f(A a, B b) {
     53     b.f(a);
     54   }
     55 
     56   void testExplicit()
     57   {
     58     // Taken from 12.3.2p2
     59     class X { X(); }; // expected-note+ {{candidate constructor}}
     60     class Y { }; // expected-note+ {{candidate constructor (the implicit}}
     61 
     62     struct Z {
     63       explicit operator X() const;
     64       explicit operator Y() const;
     65       explicit operator int() const;
     66     };
     67 
     68     Z z;
     69     // 13.3.1.4p1 & 8.5p16:
     70     Y y2 = z; // expected-error {{no viable conversion from 'Z' to 'Y'}}
     71     Y y2b(z);
     72     Y y3 = (Y)z;
     73     Y y4 = Y(z);
     74     Y y5 = static_cast<Y>(z);
     75     // 13.3.1.5p1 & 8.5p16:
     76     int i1 = (int)z;
     77     int i2 = int(z);
     78     int i3 = static_cast<int>(z);
     79     int i4(z);
     80     // 13.3.1.6p1 & 8.5.3p5:
     81     const Y& y6 = z; // expected-error {{no viable conversion from 'Z' to 'const Y'}}
     82     const int& y7 = z; // expected-error {{no viable conversion from 'Z' to 'const int'}}
     83     const Y& y8(z);
     84     const int& y9(z);
     85 
     86     // Y is an aggregate, so aggregate-initialization is performed and the
     87     // conversion function is not considered.
     88     const Y y10{z}; // expected-error {{excess elements}}
     89     const Y& y11{z}; // expected-error {{no viable conversion from 'Z' to 'const Y'}}
     90     const int& y12{z};
     91 
     92     // X is not an aggregate, so constructors are considered.
     93     // However, by 13.3.3.1/4, only standard conversion sequences and
     94     // ellipsis conversion sequences are considered here, so this is not
     95     // allowed.
     96     // FIXME: It's not really clear that this is a sensible restriction for this
     97     // case. g++ allows this, EDG does not.
     98     const X x1{z}; // expected-error {{no matching constructor}}
     99     const X& x2{z}; // expected-error {{no matching constructor}}
    100   }
    101 
    102   void testBool() {
    103     struct Bool {
    104       operator bool();
    105     };
    106 
    107     struct NotBool {
    108       explicit operator bool(); // expected-note {{conversion to integral type 'bool'}}
    109     };
    110     Bool    b;
    111     NotBool n;
    112 
    113     (void) (1 + b);
    114     (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'NotBool')}}
    115 
    116     // 5.3.1p9:
    117     (void) (!b);
    118     (void) (!n);
    119 
    120     // 5.14p1:
    121     (void) (b && true);
    122     (void) (n && true);
    123 
    124     // 5.15p1:
    125     (void) (b || true);
    126     (void) (n || true);
    127 
    128     // 5.16p1:
    129     (void) (b ? 0 : 1);
    130     (void) (n ? 0: 1);
    131 
    132     // 5.19p5:
    133     // TODO: After constexpr has been implemented
    134 
    135     // 6.4p4:
    136     if (b) {}
    137     if (n) {}
    138 
    139     // 6.4.2p2:
    140     switch (b) {} // expected-warning {{switch condition has boolean value}}
    141     switch (n) {} // expected-error {{switch condition type 'NotBool' requires explicit conversion to 'bool'}} \
    142                      expected-warning {{switch condition has boolean value}}
    143 
    144     // 6.5.1:
    145     while (b) {}
    146     while (n) {}
    147 
    148     // 6.5.2p1:
    149     do {} while (b);
    150     do {} while (n);
    151 
    152     // 6.5.3:
    153     for (;b;) {}
    154     for (;n;) {}
    155 
    156     // 13.3.1.5p1:
    157     bool direct1(b);
    158     bool direct2(n);
    159     int direct3(b);
    160     int direct4(n); // expected-error {{no viable conversion}}
    161     const bool &direct5(b);
    162     const bool &direct6(n);
    163     const int &direct7(b);
    164     const int &direct8(n); // expected-error {{no viable conversion}}
    165     bool directList1{b};
    166     bool directList2{n};
    167     int directList3{b};
    168     int directList4{n}; // expected-error {{no viable conversion}}
    169     const bool &directList5{b};
    170     const bool &directList6{n};
    171     const int &directList7{b};
    172     const int &directList8{n}; // expected-error {{no viable conversion}}
    173     bool copy1 = b;
    174     bool copy2 = n; // expected-error {{no viable conversion}}
    175     int copy3 = b;
    176     int copy4 = n; // expected-error {{no viable conversion}}
    177     const bool &copy5 = b;
    178     const bool &copy6 = n; // expected-error {{no viable conversion}}
    179     const int &copy7 = b;
    180     const int &copy8 = n; // expected-error {{no viable conversion}}
    181     bool copyList1 = {b};
    182     bool copyList2 = {n}; // expected-error {{no viable conversion}}
    183     int copyList3 = {b};
    184     int copyList4 = {n}; // expected-error {{no viable conversion}}
    185     const bool &copyList5 = {b};
    186     const bool &copyList6 = {n}; // expected-error {{no viable conversion}}
    187     const int &copyList7 = {b};
    188     const int &copyList8 = {n}; // expected-error {{no viable conversion}}
    189   }
    190 
    191   void testNew()
    192   {
    193     // 5.3.4p6:
    194     struct Int {
    195       operator int();
    196     };
    197     struct NotInt {
    198       explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}}
    199     };
    200 
    201     Int    i;
    202     NotInt ni;
    203 
    204     new int[i];
    205     new int[ni]; // expected-error {{array size expression of type 'NotInt' requires explicit conversion to type 'int'}}
    206   }
    207 
    208   void testDelete()
    209   {
    210     // 5.3.5pp2:
    211     struct Ptr {
    212       operator int*();
    213     };
    214     struct NotPtr {
    215       explicit operator int*(); // expected-note {{conversion}}
    216     };
    217 
    218     Ptr    p;
    219     NotPtr np;
    220 
    221     delete p;
    222     delete np; // expected-error {{converting delete expression from type 'NotPtr' to type 'int *' invokes an explicit conversion function}}
    223   }
    224 
    225   void testFunctionPointer()
    226   {
    227     // 13.3.1.1.2p2:
    228     using Func = void(*)(int);
    229 
    230     struct FP {
    231       operator Func();
    232     };
    233     struct NotFP {
    234       explicit operator Func();
    235     };
    236 
    237     FP    fp;
    238     NotFP nfp;
    239     fp(1);
    240     nfp(1); // expected-error {{type 'NotFP' does not provide a call operator}}
    241   }
    242 }
    243 
    244 namespace pr8264 {
    245   struct Test {
    246   explicit explicit Test(int x);  // expected-warning{{duplicate 'explicit' declaration specifier}}
    247   };
    248 }
    249 
    250 namespace PR18777 {
    251   struct S { explicit operator bool() const; } s;
    252   int *p = new int(s); // expected-error {{no viable conversion}}
    253 }
    254