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 
     48     struct Z {
     49       explicit operator Y() const;
     50       explicit operator int() const;
     51     };
     52 
     53     Z z;
     54     // 13.3.1.4p1 & 8.5p16:
     55     Y y2 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'Conversion::Y'}}
     56     Y y3 = (Y)z;
     57     Y y4 = Y(z);
     58     Y y5 = static_cast<Y>(z);
     59     // 13.3.1.5p1 & 8.5p16:
     60     int i1 = (int)z;
     61     int i2 = int(z);
     62     int i3 = static_cast<int>(z);
     63     int i4(z);
     64     // 13.3.1.6p1 & 8.5.3p5:
     65     const Y& y6 = z; // expected-error {{no viable conversion from 'Conversion::Z' to 'const Conversion::Y'}}
     66     const int& y7(z);
     67   }
     68 
     69   void testBool() {
     70     struct Bool {
     71       operator bool();
     72     };
     73 
     74     struct NotBool {
     75       explicit operator bool(); // expected-note {{conversion to integral type 'bool'}}
     76     };
     77     Bool    b;
     78     NotBool n;
     79 
     80     (void) (1 + b);
     81     (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'Conversion::NotBool')}}
     82 
     83     // 5.3.1p9:
     84     (void) (!b);
     85     (void) (!n);
     86 
     87     // 5.14p1:
     88     (void) (b && true);
     89     (void) (n && true);
     90 
     91     // 5.15p1:
     92     (void) (b || true);
     93     (void) (n || true);
     94 
     95     // 5.16p1:
     96     (void) (b ? 0 : 1);
     97     (void) (n ? 0: 1);
     98 
     99     // 5.19p5:
    100     // TODO: After constexpr has been implemented
    101 
    102     // 6.4p4:
    103     if (b) {}
    104     if (n) {}
    105 
    106     // 6.4.2p2:
    107     switch (b) {} // expected-warning {{switch condition has boolean value}}
    108     switch (n) {} // expected-error {{switch condition type 'Conversion::NotBool' requires explicit conversion to 'bool'}} \
    109                      expected-warning {{switch condition has boolean value}}
    110 
    111     // 6.5.1:
    112     while (b) {}
    113     while (n) {}
    114 
    115     // 6.5.2p1:
    116     do {} while (b);
    117     do {} while (n);
    118 
    119     // 6.5.3:
    120     for (;b;) {}
    121     for (;n;) {}
    122   }
    123 
    124   void testNew()
    125   {
    126     // 5.3.4p6:
    127     struct Int {
    128       operator int();
    129     };
    130     struct NotInt {
    131       explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}}
    132     };
    133 
    134     Int    i;
    135     NotInt ni;
    136 
    137     new int[i];
    138     new int[ni]; // expected-error {{array size expression of type 'Conversion::NotInt' requires explicit conversion to type 'int'}}
    139   }
    140 
    141   void testDelete()
    142   {
    143     // 5.3.5pp2:
    144     struct Ptr {
    145       operator int*();
    146     };
    147     struct NotPtr {
    148       explicit operator int*();
    149     };
    150 
    151     Ptr    p;
    152     NotPtr np;
    153 
    154     delete p;
    155     delete np; // expected-error {{cannot delete expression of type 'Conversion::NotPtr'}}
    156   }
    157 
    158   void testFunctionPointer()
    159   {
    160     // 13.3.1.1.2p2:
    161     using Func = void(*)(int);
    162 
    163     struct FP {
    164       operator Func();
    165     };
    166     struct NotFP {
    167       explicit operator Func();
    168     };
    169 
    170     FP    fp;
    171     NotFP nfp;
    172     fp(1);
    173     nfp(1); // expected-error {{type 'Conversion::NotFP' does not provide a call operator}}
    174   }
    175 }
    176