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 {
      8   explicit B(int);
      9 };
     10 
     11 B::B(int) { }
     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 
     23 namespace Conversion {
     24   struct A {
     25     operator int();
     26     explicit operator bool();
     27   };
     28 
     29   A::operator bool() { return false; }
     30 
     31   struct B {
     32     void f(int);
     33     void f(bool);
     34   };
     35 
     36   void f(A a, B b) {
     37     b.f(a);
     38   }
     39 
     40   void testExplicit()
     41   {
     42     // Taken from 12.3.2p2
     43     class Y { }; // expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y &' for 1st argument}} \
     44 					          expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y &&' for 1st argument}} \
     45                     expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y &' for 1st argument}} \
     46                     expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \
     47 					expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
     48 					expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \
     49 					expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} \
     50 					expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
     51 					expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y' for 1st argument}} \
     52 					expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}} \
     53 					expected-note {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'Conversion::Z' to 'const Conversion::Y' for 1st argument}} \
     54           expected-note {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'Conversion::Z' to 'Conversion::Y &&' for 1st argument}} \
     55 					expected-note {{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
     56     struct Z {
     57       explicit operator Y() const;
     58       explicit operator int() const;
     59     };
     60 
     61     Z z;
     62     // 13.3.1.4p1 & 8.5p16:
     63     Y y2 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'Conversion::Y'}}
     64     // FIXME: These are well-formed per C++0x 13.3.1.4p1 (see DR899).
     65     Y y3 = (Y)z; // expected-error {{no matching conversion for C-style cast from 'Conversion::Z' to 'Conversion::Y''}}
     66     Y y4 = Y(z); // expected-error {{no matching conversion for functional-style cast from 'Conversion::Z' to 'Conversion::Y'}}
     67     Y y5 = static_cast<Y>(z); // expected-error {{no matching conversion for static_cast from 'Conversion::Z' to 'Conversion::Y'}}
     68     // 13.3.1.5p1 & 8.5p16:
     69     int i1 = (int)z;
     70     int i2 = int(z);
     71     int i3 = static_cast<int>(z);
     72     int i4(z);
     73     // 13.3.1.6p1 & 8.5.3p5:
     74     const Y& y6 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'const Conversion::Y'}}
     75     const int& y7(z);
     76   }
     77 
     78   void testBool() {
     79     struct Bool {
     80       operator bool();
     81     };
     82 
     83     struct NotBool {
     84       explicit operator bool(); // expected-note {{conversion to integral type 'bool'}}
     85     };
     86     Bool    b;
     87     NotBool n;
     88 
     89     (void) (1 + b);
     90     (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'Conversion::NotBool')}}
     91 
     92     // 5.3.1p9:
     93     (void) (!b);
     94     (void) (!n);
     95 
     96     // 5.14p1:
     97     (void) (b && true);
     98     (void) (n && true);
     99 
    100     // 5.15p1:
    101     (void) (b || true);
    102     (void) (n || true);
    103 
    104     // 5.16p1:
    105     (void) (b ? 0 : 1);
    106     (void) (n ? 0: 1);
    107 
    108     // 5.19p5:
    109     // TODO: After constexpr has been implemented
    110 
    111     // 6.4p4:
    112     if (b) {}
    113     if (n) {}
    114 
    115     // 6.4.2p2:
    116     switch (b) {} // expected-warning {{switch condition has boolean value}}
    117     switch (n) {} // expected-error {{switch condition type 'Conversion::NotBool' requires explicit conversion to 'bool'}} \
    118                      expected-warning {{switch condition has boolean value}}
    119 
    120     // 6.5.1:
    121     while (b) {}
    122     while (n) {}
    123 
    124     // 6.5.2p1:
    125     do {} while (b);
    126     do {} while (n);
    127 
    128     // 6.5.3:
    129     for (;b;) {}
    130     for (;n;) {}
    131   }
    132 
    133   void testNew()
    134   {
    135     // 5.3.4p6:
    136     struct Int {
    137       operator int();
    138     };
    139     struct NotInt {
    140       explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}}
    141     };
    142 
    143     Int    i;
    144     NotInt ni;
    145 
    146     new int[i];
    147     new int[ni]; // expected-error {{array size expression of type 'Conversion::NotInt' requires explicit conversion to type 'int'}}
    148   }
    149 
    150   void testDelete()
    151   {
    152     // 5.3.5pp2:
    153     struct Ptr {
    154       operator int*();
    155     };
    156     struct NotPtr {
    157       explicit operator int*();
    158     };
    159 
    160     Ptr    p;
    161     NotPtr np;
    162 
    163     delete p;
    164     delete np; // expected-error {{cannot delete expression of type 'Conversion::NotPtr'}}
    165   }
    166 
    167   void testFunctionPointer()
    168   {
    169     // 13.3.1.1.2p2:
    170     using Func = void(*)(int);
    171 
    172     struct FP {
    173       operator Func();
    174     };
    175     struct NotFP {
    176       explicit operator Func();
    177     };
    178 
    179     FP    fp;
    180     NotFP nfp;
    181     fp(1);
    182     nfp(1); // expected-error {{type 'Conversion::NotFP' does not provide a call operator}}
    183   }
    184 }
    185