forked from OSchip/llvm-project
ABI handling: Fix nasty thinko where IRgen could generate an out-of-bounds read
when generating a coercion for ABI handling purposes. - This may only manifest itself when building at -O0, but the practical effect is that other arguments may get clobbered. - <rdar://problem/6930451> [irgen] ABI coercion clobbers other arguments llvm-svn: 72932
This commit is contained in:
parent
327f0b5593
commit
4be99ff767
|
@ -1638,13 +1638,7 @@ static void CreateCoercedStore(llvm::Value *Src,
|
|||
uint64_t DstSize = CGF.CGM.getTargetData().getTypeAllocSize(DstTy);
|
||||
|
||||
// If store is legal, just bitcast the src pointer.
|
||||
if (SrcSize >= DstSize) {
|
||||
// Generally SrcSize is never greater than DstSize, since this means we are
|
||||
// losing bits. However, this can happen in cases where the structure has
|
||||
// additional padding, for example due to a user specified alignment.
|
||||
//
|
||||
// FIXME: Assert that we aren't truncating non-padding bits when have access
|
||||
// to that information.
|
||||
if (SrcSize <= DstSize) {
|
||||
llvm::Value *Casted =
|
||||
CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy));
|
||||
// FIXME: Use better alignment / avoid requiring aligned store.
|
||||
|
@ -1652,6 +1646,13 @@ static void CreateCoercedStore(llvm::Value *Src,
|
|||
} else {
|
||||
// Otherwise do coercion through memory. This is stupid, but
|
||||
// simple.
|
||||
|
||||
// Generally SrcSize is never greater than DstSize, since this means we are
|
||||
// losing bits. However, this can happen in cases where the structure has
|
||||
// additional padding, for example due to a user specified alignment.
|
||||
//
|
||||
// FIXME: Assert that we aren't truncating non-padding bits when have access
|
||||
// to that information.
|
||||
llvm::Value *Tmp = CGF.CreateTempAlloca(SrcTy);
|
||||
CGF.Builder.CreateStore(Src, Tmp);
|
||||
llvm::Value *Casted =
|
||||
|
|
|
@ -82,4 +82,10 @@ void f16(float a, float b, float c, float d, float e, float f, float g, float h,
|
|||
void f17(float a, float b, float c, float d, float e, float f, float g, float h,
|
||||
long double X) {}
|
||||
|
||||
// Check for valid coercion.
|
||||
// RUN: grep '.1 = bitcast i64. .tmp to .struct.f18_s0.' %t &&
|
||||
// RUN: grep '.2 = load .struct.f18_s0. .1, align 1' %t &&
|
||||
// RUN: grep 'store .struct.f18_s0 .2, .struct.f18_s0. .f18_arg1' %t &&
|
||||
void f18(int a, struct f18_s0 { int f0; } f18_arg1) {}
|
||||
|
||||
// RUN: true
|
||||
|
|
Loading…
Reference in New Issue