From 4be99ff767f6bfefa9e6aafe7aefaa3c4dd2fb23 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 5 Jun 2009 07:58:54 +0000 Subject: [PATCH] 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. - [irgen] ABI coercion clobbers other arguments llvm-svn: 72932 --- clang/lib/CodeGen/CGCall.cpp | 15 ++++++++------- clang/test/CodeGen/x86_64-arguments.c | 6 ++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 954ac530684d..248619fc2d59 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -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 = diff --git a/clang/test/CodeGen/x86_64-arguments.c b/clang/test/CodeGen/x86_64-arguments.c index 6f7ec82872be..0b68afdb4edd 100644 --- a/clang/test/CodeGen/x86_64-arguments.c +++ b/clang/test/CodeGen/x86_64-arguments.c @@ -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