250 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			250 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			C++
		
	
	
	
| // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 | |
| namespace Constructor {
 | |
| struct A {
 | |
|   A(int);
 | |
| };
 | |
| 
 | |
| struct B { // expected-note+ {{candidate}}
 | |
|   explicit B(int);
 | |
| };
 | |
| 
 | |
| B::B(int) { } // expected-note+ {{here}}
 | |
| 
 | |
| struct C {
 | |
|   void f(const A&);
 | |
|   void f(const B&);
 | |
| };
 | |
| 
 | |
| void f(C c) {
 | |
|   c.f(10);
 | |
| }
 | |
| 
 | |
| A a0 = 0;
 | |
| A a1(0);
 | |
| A &&a2 = 0;
 | |
| A &&a3(0);
 | |
| A a4{0};
 | |
| A &&a5 = {0};
 | |
| A &&a6{0};
 | |
| 
 | |
| B b0 = 0; // expected-error {{no viable conversion}}
 | |
| B b1(0);
 | |
| B &&b2 = 0; // expected-error {{could not bind}}
 | |
| B &&b3(0); // expected-error {{could not bind}}
 | |
| B b4{0};
 | |
| B &&b5 = {0}; // expected-error {{chosen constructor is explicit}}
 | |
| B &&b6{0};
 | |
| }
 | |
| 
 | |
| namespace Conversion {
 | |
|   struct A {
 | |
|     operator int();
 | |
|     explicit operator bool();
 | |
|   };
 | |
| 
 | |
|   A::operator bool() { return false; } 
 | |
| 
 | |
|   struct B {
 | |
|     void f(int);
 | |
|     void f(bool);
 | |
|   };
 | |
| 
 | |
|   void f(A a, B b) {
 | |
|     b.f(a);
 | |
|   }
 | |
|   
 | |
|   void testExplicit()
 | |
|   {
 | |
|     // Taken from 12.3.2p2
 | |
|     class X { X(); };
 | |
|     class Y { }; // expected-note+ {{candidate constructor (the implicit}}
 | |
| 
 | |
|     struct Z {
 | |
|       explicit operator X() const;
 | |
|       explicit operator Y() const;
 | |
|       explicit operator int() const;
 | |
|     };
 | |
|     
 | |
|     Z z;
 | |
|     // 13.3.1.4p1 & 8.5p16:
 | |
|     Y y2 = z; // expected-error {{no viable conversion from 'Z' to 'Y'}}
 | |
|     Y y2b(z);
 | |
|     Y y3 = (Y)z;
 | |
|     Y y4 = Y(z);
 | |
|     Y y5 = static_cast<Y>(z);
 | |
|     // 13.3.1.5p1 & 8.5p16:
 | |
|     int i1 = (int)z;
 | |
|     int i2 = int(z);
 | |
|     int i3 = static_cast<int>(z);
 | |
|     int i4(z);
 | |
|     // 13.3.1.6p1 & 8.5.3p5:
 | |
|     const Y& y6 = z; // expected-error {{no viable conversion from 'Z' to 'const Y'}}
 | |
|     const int& y7 = z; // expected-error {{no viable conversion from 'Z' to 'const int'}}
 | |
|     const Y& y8(z);
 | |
|     const int& y9(z);
 | |
| 
 | |
|     // Y is an aggregate, so aggregate-initialization is performed and the
 | |
|     // conversion function is not considered.
 | |
|     const Y y10{z}; // expected-error {{excess elements}}
 | |
|     const Y& y11{z}; // expected-error {{excess elements}} expected-note {{in initialization of temporary of type 'const Y'}}
 | |
|     const int& y12{z};
 | |
| 
 | |
|     // X is not an aggregate, so constructors are considered,
 | |
|     // per 13.3.3.1/4 & DR1467.
 | |
|     const X x1{z};
 | |
|     const X& x2{z};
 | |
|   }
 | |
|   
 | |
|   void testBool() {
 | |
|     struct Bool {
 | |
|       operator bool();
 | |
|     };
 | |
| 
 | |
|     struct NotBool {
 | |
|       explicit operator bool(); // expected-note {{conversion to integral type 'bool'}}
 | |
|     };
 | |
|     Bool    b;
 | |
|     NotBool n;
 | |
| 
 | |
|     (void) (1 + b);
 | |
|     (void) (1 + n); // expected-error {{invalid operands to binary expression ('int' and 'NotBool')}}
 | |
|     
 | |
|     // 5.3.1p9:
 | |
|     (void) (!b);
 | |
|     (void) (!n);
 | |
|     
 | |
|     // 5.14p1:
 | |
|     (void) (b && true);
 | |
|     (void) (n && true);
 | |
|     
 | |
|     // 5.15p1:
 | |
|     (void) (b || true);
 | |
|     (void) (n || true);
 | |
|     
 | |
|     // 5.16p1:
 | |
|     (void) (b ? 0 : 1);
 | |
|     (void) (n ? 0: 1);
 | |
|     
 | |
|     // 5.19p5:
 | |
|     // TODO: After constexpr has been implemented
 | |
|     
 | |
|     // 6.4p4:
 | |
|     if (b) {}
 | |
|     if (n) {}
 | |
|     
 | |
|     // 6.4.2p2:
 | |
|     switch (b) {} // expected-warning {{switch condition has boolean value}}
 | |
|     switch (n) {} // expected-error {{switch condition type 'NotBool' requires explicit conversion to 'bool'}} \
 | |
|                      expected-warning {{switch condition has boolean value}}
 | |
|     
 | |
|     // 6.5.1:
 | |
|     while (b) {}
 | |
|     while (n) {}
 | |
|     
 | |
|     // 6.5.2p1:
 | |
|     do {} while (b);
 | |
|     do {} while (n);
 | |
|     
 | |
|     // 6.5.3:
 | |
|     for (;b;) {}
 | |
|     for (;n;) {}
 | |
| 
 | |
|     // 13.3.1.5p1:
 | |
|     bool direct1(b);
 | |
|     bool direct2(n);
 | |
|     int direct3(b);
 | |
|     int direct4(n); // expected-error {{no viable conversion}}
 | |
|     const bool &direct5(b);
 | |
|     const bool &direct6(n);
 | |
|     const int &direct7(b);
 | |
|     const int &direct8(n); // expected-error {{no viable conversion}}
 | |
|     bool directList1{b};
 | |
|     bool directList2{n};
 | |
|     int directList3{b};
 | |
|     int directList4{n}; // expected-error {{no viable conversion}}
 | |
|     const bool &directList5{b};
 | |
|     const bool &directList6{n};
 | |
|     const int &directList7{b};
 | |
|     const int &directList8{n}; // expected-error {{no viable conversion}}
 | |
|     bool copy1 = b;
 | |
|     bool copy2 = n; // expected-error {{no viable conversion}}
 | |
|     int copy3 = b;
 | |
|     int copy4 = n; // expected-error {{no viable conversion}}
 | |
|     const bool ©5 = b;
 | |
|     const bool ©6 = n; // expected-error {{no viable conversion}}
 | |
|     const int ©7 = b;
 | |
|     const int ©8 = n; // expected-error {{no viable conversion}}
 | |
|     bool copyList1 = {b};
 | |
|     bool copyList2 = {n}; // expected-error {{no viable conversion}}
 | |
|     int copyList3 = {b};
 | |
|     int copyList4 = {n}; // expected-error {{no viable conversion}}
 | |
|     const bool ©List5 = {b};
 | |
|     const bool ©List6 = {n}; // expected-error {{no viable conversion}}
 | |
|     const int ©List7 = {b};
 | |
|     const int ©List8 = {n}; // expected-error {{no viable conversion}}
 | |
|   }
 | |
|   
 | |
|   void testNew()
 | |
|   {
 | |
|     // 5.3.4p6:
 | |
|     struct Int {
 | |
|       operator int();
 | |
|     };
 | |
|     struct NotInt {
 | |
|       explicit operator int(); // expected-note {{conversion to integral type 'int' declared here}}
 | |
|     };
 | |
|     
 | |
|     Int    i;
 | |
|     NotInt ni;
 | |
|     
 | |
|     new int[i];
 | |
|     new int[ni]; // expected-error {{array size expression of type 'NotInt' requires explicit conversion to type 'int'}}
 | |
|   }
 | |
|   
 | |
|   void testDelete()
 | |
|   {
 | |
|     // 5.3.5pp2:
 | |
|     struct Ptr {
 | |
|       operator int*();
 | |
|     };
 | |
|     struct NotPtr {
 | |
|       explicit operator int*(); // expected-note {{conversion}}
 | |
|     };
 | |
|     
 | |
|     Ptr    p;
 | |
|     NotPtr np;
 | |
|     
 | |
|     delete p;
 | |
|     delete np; // expected-error {{converting delete expression from type 'NotPtr' to type 'int *' invokes an explicit conversion function}}
 | |
|   }
 | |
|   
 | |
|   void testFunctionPointer()
 | |
|   {
 | |
|     // 13.3.1.1.2p2:
 | |
|     using Func = void(*)(int);
 | |
|     
 | |
|     struct FP {
 | |
|       operator Func();
 | |
|     };
 | |
|     struct NotFP {
 | |
|       explicit operator Func();
 | |
|     };
 | |
|     
 | |
|     FP    fp;
 | |
|     NotFP nfp;
 | |
|     fp(1);
 | |
|     nfp(1); // expected-error {{type 'NotFP' does not provide a call operator}}
 | |
|   }
 | |
| }
 | |
| 
 | |
| namespace pr8264 {
 | |
|   struct Test {
 | |
|   explicit explicit Test(int x);  // expected-warning{{duplicate 'explicit' declaration specifier}}
 | |
|   };
 | |
| }
 | |
| 
 | |
| namespace PR18777 {
 | |
|   struct S { explicit operator bool() const; } s;
 | |
|   int *p = new int(s); // expected-error {{no viable conversion}}
 | |
| }
 |