]> granicus.if.org Git - clang/commitdiff
Sema: Fix explicit address space cast involving void pointers
authorYaxun Liu <Yaxun.Liu@amd.com>
Fri, 3 Aug 2018 03:18:56 +0000 (03:18 +0000)
committerYaxun Liu <Yaxun.Liu@amd.com>
Fri, 3 Aug 2018 03:18:56 +0000 (03:18 +0000)
Explicit cast of a void pointer to a pointer type in different address space is
incorrectly classified as bitcast, which causes invalid bitcast in codegen.

The patch fixes that by checking the address space of the source and destination
type and set the correct cast kind.

Differential Revision: https://reviews.llvm.org/D50003

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@338805 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaCast.cpp
test/CodeGenCXX/address-space-cast.cpp

index 57aac80f5ad2eb67855bf95b7046a8e7dcb295a3..8599fe09a5d61c120b28bc74db31b7d59471a2c8 100644 (file)
@@ -1044,6 +1044,17 @@ void CastOperation::CheckStaticCast() {
   }
 }
 
+static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType) {
+  auto *SrcPtrType = SrcType->getAs<PointerType>();
+  if (!SrcPtrType)
+    return false;
+  auto *DestPtrType = DestType->getAs<PointerType>();
+  if (!DestPtrType)
+    return false;
+  return SrcPtrType->getPointeeType().getAddressSpace() !=
+         DestPtrType->getPointeeType().getAddressSpace();
+}
+
 /// TryStaticCast - Check if a static cast can be performed, and do so if
 /// possible. If @p CStyle, ignore access restrictions on hierarchy casting
 /// and casting away constness.
@@ -1185,7 +1196,9 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
               return TC_Failed;
             }
           }
-          Kind = CK_BitCast;
+          Kind = IsAddressSpaceConversion(SrcType, DestType)
+                     ? CK_AddressSpaceConversion
+                     : CK_BitCast;
           return TC_Success;
         }
 
@@ -1964,12 +1977,6 @@ static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType,
   return Result.isUsable();
 }
 
-static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType) {
-  return SrcType->isPointerType() && DestType->isPointerType() &&
-         SrcType->getAs<PointerType>()->getPointeeType().getAddressSpace() !=
-             DestType->getAs<PointerType>()->getPointeeType().getAddressSpace();
-}
-
 static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr,
                                         QualType DestType, bool CStyle,
                                         SourceRange OpRange,
index 334a1a63e6277bc75a48bd858b437a0c4550883d..e0cf3c199b88ac0c8c75cd28dacca1c9cbe1a35a 100644 (file)
@@ -3,13 +3,63 @@
 #define __private__ __attribute__((address_space(5)))
 
 void func_pchar(__private__ char *x);
+void func_pvoid(__private__ void *x);
+void func_pint(__private__ int *x);
 
-void test_cast(char *gen_ptr) {
+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_ptr = (__private__ char *)gen_ptr;
+  __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_ptr);
+  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);
 }