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:
Daniel Dunbar 2009-06-05 07:58:54 +00:00
parent 327f0b5593
commit 4be99ff767
2 changed files with 14 additions and 7 deletions

View File

@ -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 =

View File

@ -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