198 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			198 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // RUN: %clang_cc1 -fsyntax-only -verify %s
 | |
| 
 | |
| // This test checks for the various conversions and casting operations
 | |
| // with address-space-qualified pointers.
 | |
| 
 | |
| struct A { virtual ~A() {} };
 | |
| struct B : A { };
 | |
| 
 | |
| typedef void *void_ptr;
 | |
| typedef void __attribute__((address_space(1))) *void_ptr_1;
 | |
| typedef void __attribute__((address_space(2))) *void_ptr_2;
 | |
| 
 | |
| typedef int *int_ptr;
 | |
| typedef int __attribute__((address_space(1))) *int_ptr_1;
 | |
| typedef int __attribute__((address_space(2))) *int_ptr_2;
 | |
| 
 | |
| typedef A *A_ptr;
 | |
| typedef A __attribute__((address_space(1))) *A_ptr_1;
 | |
| typedef A __attribute__((address_space(2))) *A_ptr_2;
 | |
| 
 | |
| typedef B *B_ptr;
 | |
| typedef B __attribute__((address_space(1))) *B_ptr_1;
 | |
| typedef B __attribute__((address_space(2))) *B_ptr_2;
 | |
| 
 | |
| void test_const_cast(int_ptr ip, int_ptr_1 ip1, int_ptr_2 ip2,
 | |
|                      A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
 | |
|                      const int *cip, 
 | |
|                      const int __attribute__((address_space(1))) *cip1) {
 | |
|   // Cannot use const_cast to cast between address spaces, add an
 | |
|   // address space, or remove an address space.
 | |
|   (void)const_cast<int_ptr>(ip1); // expected-error{{is not allowed}}
 | |
|   (void)const_cast<int_ptr>(ip2); // expected-error{{is not allowed}}
 | |
|   (void)const_cast<int_ptr_1>(ip); // expected-error{{is not allowed}}
 | |
|   (void)const_cast<int_ptr_1>(ip2); // expected-error{{is not allowed}}
 | |
|   (void)const_cast<int_ptr_2>(ip); // expected-error{{is not allowed}}
 | |
|   (void)const_cast<int_ptr_2>(ip1); // expected-error{{is not allowed}}
 | |
| 
 | |
|   (void)const_cast<A_ptr>(ap1); // expected-error{{is not allowed}}
 | |
|   (void)const_cast<A_ptr>(ap2); // expected-error{{is not allowed}}
 | |
|   (void)const_cast<A_ptr_1>(ap); // expected-error{{is not allowed}}
 | |
|   (void)const_cast<A_ptr_1>(ap2); // expected-error{{is not allowed}}
 | |
|   (void)const_cast<A_ptr_2>(ap); // expected-error{{is not allowed}}
 | |
|   (void)const_cast<A_ptr_2>(ap1); // expected-error{{is not allowed}}
 | |
| 
 | |
|   // It's acceptable to cast away constness.
 | |
|   (void)const_cast<int_ptr>(cip);
 | |
|   (void)const_cast<int_ptr_1>(cip1);
 | |
| }
 | |
| 
 | |
| void test_static_cast(void_ptr vp, void_ptr_1 vp1, void_ptr_2 vp2,
 | |
|                       A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
 | |
|                       B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2) {
 | |
|   // Well-formed upcast
 | |
|   (void)static_cast<A_ptr>(bp);
 | |
|   (void)static_cast<A_ptr_1>(bp1);
 | |
|   (void)static_cast<A_ptr_2>(bp2);
 | |
| 
 | |
|   // Well-formed downcast
 | |
|   (void)static_cast<B_ptr>(ap);
 | |
|   (void)static_cast<B_ptr_1>(ap1);
 | |
|   (void)static_cast<B_ptr_2>(ap2);
 | |
| 
 | |
|   // Well-formed cast to/from void
 | |
|   (void)static_cast<void_ptr>(ap);
 | |
|   (void)static_cast<void_ptr_1>(ap1);
 | |
|   (void)static_cast<void_ptr_2>(ap2);
 | |
|   (void)static_cast<A_ptr>(vp);
 | |
|   (void)static_cast<A_ptr_1>(vp1);
 | |
|   (void)static_cast<A_ptr_2>(vp2);
 | |
|   
 | |
|   // Ill-formed upcasts
 | |
|   (void)static_cast<A_ptr>(bp1); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<A_ptr>(bp2); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<A_ptr_1>(bp); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<A_ptr_1>(bp2); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<A_ptr_2>(bp); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<A_ptr_2>(bp1); // expected-error{{is not allowed}}
 | |
| 
 | |
|   // Ill-formed downcasts
 | |
|   (void)static_cast<B_ptr>(ap1); // expected-error{{casts away qualifiers}}
 | |
|   (void)static_cast<B_ptr>(ap2); // expected-error{{casts away qualifiers}}
 | |
|   (void)static_cast<B_ptr_1>(ap); // expected-error{{casts away qualifiers}}
 | |
|   (void)static_cast<B_ptr_1>(ap2); // expected-error{{casts away qualifiers}}
 | |
|   (void)static_cast<B_ptr_2>(ap); // expected-error{{casts away qualifiers}}
 | |
|   (void)static_cast<B_ptr_2>(ap1); // expected-error{{casts away qualifiers}}
 | |
| 
 | |
|   // Ill-formed cast to/from void
 | |
|   (void)static_cast<void_ptr>(ap1); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<void_ptr>(ap2); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<void_ptr_1>(ap); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<void_ptr_1>(ap2); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<void_ptr_2>(ap); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<void_ptr_2>(ap1); // expected-error{{is not allowed}}
 | |
|   (void)static_cast<A_ptr>(vp1); // expected-error{{casts away qualifiers}}
 | |
|   (void)static_cast<A_ptr>(vp2); // expected-error{{casts away qualifiers}}
 | |
|   (void)static_cast<A_ptr_1>(vp); // expected-error{{casts away qualifiers}}
 | |
|   (void)static_cast<A_ptr_1>(vp2); // expected-error{{casts away qualifiers}}
 | |
|   (void)static_cast<A_ptr_2>(vp); // expected-error{{casts away qualifiers}}
 | |
|   (void)static_cast<A_ptr_2>(vp1); // expected-error{{casts away qualifiers}}
 | |
| }
 | |
| 
 | |
| void test_dynamic_cast(A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
 | |
|                        B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2) {
 | |
|   // Well-formed upcast
 | |
|   (void)dynamic_cast<A_ptr>(bp);
 | |
|   (void)dynamic_cast<A_ptr_1>(bp1);
 | |
|   (void)dynamic_cast<A_ptr_2>(bp2);
 | |
| 
 | |
|   // Well-formed downcast
 | |
|   (void)dynamic_cast<B_ptr>(ap);
 | |
|   (void)dynamic_cast<B_ptr_1>(ap1);
 | |
|   (void)dynamic_cast<B_ptr_2>(ap2);
 | |
| 
 | |
|   // Ill-formed upcasts
 | |
|   (void)dynamic_cast<A_ptr>(bp1); // expected-error{{casts away qualifiers}}
 | |
|   (void)dynamic_cast<A_ptr>(bp2); // expected-error{{casts away qualifiers}}
 | |
|   (void)dynamic_cast<A_ptr_1>(bp); // expected-error{{casts away qualifiers}}
 | |
|   (void)dynamic_cast<A_ptr_1>(bp2); // expected-error{{casts away qualifiers}}
 | |
|   (void)dynamic_cast<A_ptr_2>(bp); // expected-error{{casts away qualifiers}}
 | |
|   (void)dynamic_cast<A_ptr_2>(bp1); // expected-error{{casts away qualifiers}}
 | |
| 
 | |
|   // Ill-formed downcasts
 | |
|   (void)dynamic_cast<B_ptr>(ap1); // expected-error{{casts away qualifiers}}
 | |
|   (void)dynamic_cast<B_ptr>(ap2); // expected-error{{casts away qualifiers}}
 | |
|   (void)dynamic_cast<B_ptr_1>(ap); // expected-error{{casts away qualifiers}}
 | |
|   (void)dynamic_cast<B_ptr_1>(ap2); // expected-error{{casts away qualifiers}}
 | |
|   (void)dynamic_cast<B_ptr_2>(ap); // expected-error{{casts away qualifiers}}
 | |
|   (void)dynamic_cast<B_ptr_2>(ap1); // expected-error{{casts away qualifiers}}
 | |
| }
 | |
| 
 | |
| void test_reinterpret_cast(void_ptr vp, void_ptr_1 vp1, void_ptr_2 vp2,
 | |
|                            A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
 | |
|                            B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2,
 | |
|                            const void __attribute__((address_space(1))) *cvp1) {
 | |
|   // reinterpret_cast can be used to cast to a different address space.
 | |
|   (void)reinterpret_cast<A_ptr>(ap1);
 | |
|   (void)reinterpret_cast<A_ptr>(ap2);
 | |
|   (void)reinterpret_cast<A_ptr>(bp);
 | |
|   (void)reinterpret_cast<A_ptr>(bp1);
 | |
|   (void)reinterpret_cast<A_ptr>(bp2);
 | |
|   (void)reinterpret_cast<A_ptr>(vp);
 | |
|   (void)reinterpret_cast<A_ptr>(vp1);
 | |
|   (void)reinterpret_cast<A_ptr>(vp2);
 | |
|   (void)reinterpret_cast<A_ptr_1>(ap);
 | |
|   (void)reinterpret_cast<A_ptr_1>(ap2);
 | |
|   (void)reinterpret_cast<A_ptr_1>(bp);
 | |
|   (void)reinterpret_cast<A_ptr_1>(bp1);
 | |
|   (void)reinterpret_cast<A_ptr_1>(bp2);
 | |
|   (void)reinterpret_cast<A_ptr_1>(vp);
 | |
|   (void)reinterpret_cast<A_ptr_1>(vp1);
 | |
|   (void)reinterpret_cast<A_ptr_1>(vp2);
 | |
| 
 | |
|   // ... but don't try to cast away constness!
 | |
|   (void)reinterpret_cast<A_ptr_2>(cvp1); // expected-error{{casts away qualifiers}}
 | |
| }
 | |
| 
 | |
| void test_cstyle_cast(void_ptr vp, void_ptr_1 vp1, void_ptr_2 vp2,
 | |
|                       A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
 | |
|                       B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2,
 | |
|                       const void __attribute__((address_space(1))) *cvp1) {
 | |
|   // C-style casts are the wild west of casts.
 | |
|   (void)(A_ptr)(ap1);
 | |
|   (void)(A_ptr)(ap2);
 | |
|   (void)(A_ptr)(bp);
 | |
|   (void)(A_ptr)(bp1);
 | |
|   (void)(A_ptr)(bp2);
 | |
|   (void)(A_ptr)(vp);
 | |
|   (void)(A_ptr)(vp1);
 | |
|   (void)(A_ptr)(vp2);
 | |
|   (void)(A_ptr_1)(ap);
 | |
|   (void)(A_ptr_1)(ap2);
 | |
|   (void)(A_ptr_1)(bp);
 | |
|   (void)(A_ptr_1)(bp1);
 | |
|   (void)(A_ptr_1)(bp2);
 | |
|   (void)(A_ptr_1)(vp);
 | |
|   (void)(A_ptr_1)(vp1);
 | |
|   (void)(A_ptr_1)(vp2);
 | |
|   (void)(A_ptr_2)(cvp1);
 | |
| }
 | |
| 
 | |
| void test_implicit_conversion(void_ptr vp, void_ptr_1 vp1, void_ptr_2 vp2,
 | |
|                               A_ptr ap, A_ptr_1 ap1, A_ptr_2 ap2,
 | |
|                               B_ptr bp, B_ptr_1 bp1, B_ptr_2 bp2) {
 | |
|   // Well-formed conversions
 | |
|   void_ptr vpA = ap;
 | |
|   void_ptr_1 vp_1A = ap1;
 | |
|   void_ptr_2 vp_2A = ap2;
 | |
|   A_ptr ap_A = bp;
 | |
|   A_ptr_1 ap_A1 = bp1;
 | |
|   A_ptr_2 ap_A2 = bp2;
 | |
| 
 | |
|   // Ill-formed conversions
 | |
|   void_ptr vpB = ap1; // expected-error{{cannot initialize a variable of type}}
 | |
|   void_ptr_1 vp_1B = ap2; // expected-error{{cannot initialize a variable of type}}
 | |
|   A_ptr ap_B = bp1; // expected-error{{cannot initialize a variable of type}}
 | |
|   A_ptr_1 ap_B1 = bp2; // expected-error{{cannot initialize a variable of type}}
 | |
| }
 | 
