Bug 18567: Fix constantexpr pointer casts with address spaces.

Getting a pointer into a struct at a non-zero offset would try to
use the default address space.

llvm-svn: 206478
This commit is contained in:
Matt Arsenault 2014-04-17 17:45:37 +00:00
parent da1c510ea6
commit 10e3ef8d2d
2 changed files with 23 additions and 1 deletions

View File

@ -1063,7 +1063,9 @@ llvm::Constant *CodeGenModule::EmitConstantValue(const APValue &Value,
// Apply offset if necessary. // Apply offset if necessary.
if (!Offset->isNullValue()) { if (!Offset->isNullValue()) {
llvm::Constant *Casted = llvm::ConstantExpr::getBitCast(C, Int8PtrTy); unsigned AS = C->getType()->getPointerAddressSpace();
llvm::Type *CharPtrTy = Int8Ty->getPointerTo(AS);
llvm::Constant *Casted = llvm::ConstantExpr::getBitCast(C, CharPtrTy);
Casted = llvm::ConstantExpr::getGetElementPtr(Casted, Offset); Casted = llvm::ConstantExpr::getGetElementPtr(Casted, Offset);
C = llvm::ConstantExpr::getPointerCast(Casted, C->getType()); C = llvm::ConstantExpr::getPointerCast(Casted, C->getType());
} }

View File

@ -0,0 +1,20 @@
// RUN: %clang_cc1 %s -ffake-address-space-map -emit-llvm -o - | FileCheck %s
typedef struct {
int i;
float f; // At non-zero offset.
} ArrayStruct;
__constant ArrayStruct constant_array_struct = { 0, 0.0f };
typedef struct {
__constant float* constant_float_ptr;
} ConstantArrayPointerStruct;
// CHECK: %struct.ConstantArrayPointerStruct = type { float addrspace(3)* }
// CHECK: addrspace(3) global %struct.ConstantArrayPointerStruct { float addrspace(3)* bitcast (i8 addrspace(3)* getelementptr (i8 addrspace(3)* bitcast (%struct.ArrayStruct addrspace(3)* @constant_array_struct to i8 addrspace(3)*), i64 4) to float addrspace(3)*) }
// Bug 18567
__constant ConstantArrayPointerStruct constant_array_pointer_struct = {
&constant_array_struct.f
};