Files
clang-p2996/clang/test/CodeGenCXX/address-space-cast.cpp
Bevin Hansson 956582aa16 [Sema] Iteratively strip sugar when removing address spaces.
ASTContext::removeAddrSpaceQualType does not properly deal
with sugar. QualTypes derive their ASes from the AS on the
canonical type, not the type itself. However,
removeAddrSpaceQualType only strips the outermost qualifiers,
which means that it can fail to remove addrspace qualifiers
if there is sugar in the way.

Change the function to desugar types until the address space
really no longer exists on the corresponding QualType. This
should guarantee the removal of the address space.

This fixes the erroneous behavior in D62574.

Reviewed By: rjmccall, svenvh

Differential Revision: https://reviews.llvm.org/D83325
2020-08-11 17:26:19 +02:00

76 lines
3.1 KiB
C++

// RUN: %clang_cc1 %s -triple=amdgcn-amd-amdhsa -emit-llvm -o - | FileCheck %s
#define __private__ __attribute__((address_space(5)))
void func_pchar(__private__ char *x);
void func_pvoid(__private__ void *x);
void func_pint(__private__ int *x);
class Base {
};
class Derived : public Base {
};
void fn(Derived *p) {
__private__ Base *b = (__private__ Base *)p;
}
void test_cast(char *gen_char_ptr, void *gen_void_ptr, int *gen_int_ptr) {
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
__private__ char *priv_char_ptr = (__private__ char *)gen_char_ptr;
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
priv_char_ptr = (__private__ char *)gen_void_ptr;
// CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
priv_char_ptr = (__private__ char *)gen_int_ptr;
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
__private__ void *priv_void_ptr = (__private__ void *)gen_char_ptr;
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
priv_void_ptr = (__private__ void *)gen_void_ptr;
// CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: store i8 addrspace(5)* %[[cast]]
priv_void_ptr = (__private__ void *)gen_int_ptr;
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
// CHECK-NEXT: store i32 addrspace(5)* %[[cast]]
__private__ int *priv_int_ptr = (__private__ int *)gen_void_ptr;
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
func_pchar((__private__ char *)gen_char_ptr);
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
func_pchar((__private__ char *)gen_void_ptr);
// CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: call void @_Z10func_pcharPU3AS5c(i8 addrspace(5)* %[[cast]])
func_pchar((__private__ char *)gen_int_ptr);
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
func_pvoid((__private__ void *)gen_char_ptr);
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
func_pvoid((__private__ void *)gen_void_ptr);
// CHECK: %[[cast:.*]] = addrspacecast i32* %{{.*}} to i8 addrspace(5)*
// CHECK-NEXT: call void @_Z10func_pvoidPU3AS5v(i8 addrspace(5)* %[[cast]])
func_pvoid((__private__ void *)gen_int_ptr);
// CHECK: %[[cast:.*]] = addrspacecast i8* %{{.*}} to i32 addrspace(5)*
// CHECK-NEXT: call void @_Z9func_pintPU3AS5i(i32 addrspace(5)* %[[cast]])
func_pint((__private__ int *)gen_void_ptr);
}