• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
B(int)11 B::B(int) { }
12 
13 struct C {
14   void f(const A&);
15   void f(const B&);
16 };
17 
f(C c)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 
operator bool()29   A::operator bool() { return false; }
30 
31   struct B {
32     void f(int);
33     void f(bool);
34   };
35 
f(A a,B b)36   void f(A a, B b) {
37     b.f(a);
38   }
39 
testExplicit()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 
testBool()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 
testNew()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 
testDelete()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 
testFunctionPointer()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