From: Daniel Dunbar Date: Wed, 13 May 2009 18:54:26 +0000 (+0000) Subject: ABI handling: Fix invalid assertion, it is possible for a valid X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7ef455be9beb7a755d815bfbdc38d55d1ce59b86;p=clang ABI handling: Fix invalid assertion, it is possible for a valid coercion to be specified which truncates padding bits. It would be nice to still have the assert, but we don't have any API call for the unpadding size of a type yet. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71695 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 072cc58e08..2c89f3f50d 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1578,7 +1578,14 @@ static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr, uint64_t DstSize = CGF.CGM.getTargetData().getTypeAllocSize(Ty); // If load is legal, just bitcast the src pointer. - if (SrcSize == DstSize) { + 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. llvm::Value *Casted = CGF.Builder.CreateBitCast(SrcPtr, llvm::PointerType::getUnqual(Ty)); llvm::LoadInst *Load = CGF.Builder.CreateLoad(Casted); @@ -1586,8 +1593,6 @@ static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr, Load->setAlignment(1); return Load; } else { - assert(SrcSize < DstSize && "Coercion is losing source bits!"); - // Otherwise do coercion through memory. This is stupid, but // simple. llvm::Value *Tmp = CGF.CreateTempAlloca(Ty); @@ -1617,14 +1622,19 @@ 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) { + 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. llvm::Value *Casted = CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy)); // FIXME: Use better alignment / avoid requiring aligned store. CGF.Builder.CreateStore(Src, Casted)->setAlignment(1); } else { - assert(SrcSize > DstSize && "Coercion is missing bits!"); - // Otherwise do coercion through memory. This is stupid, but // simple. llvm::Value *Tmp = CGF.CreateTempAlloca(SrcTy); diff --git a/test/CodeGen/x86_32-arguments.c b/test/CodeGen/x86_32-arguments.c index fae49cbdd8..8980c66b20 100644 --- a/test/CodeGen/x86_32-arguments.c +++ b/test/CodeGen/x86_32-arguments.c @@ -131,7 +131,7 @@ struct s29 { struct { } a[1]; char b; char c; } f29(void) {} struct s30 { char a; char b : 4; } f30(void) {} // RUN: grep 'define float @f31()' %t && -struct s31 { char : 0; float b; char : 0} f31(void) {} +struct s31 { char : 0; float b; char : 0; } f31(void) {} // RUN: grep 'define i32 @f32()' %t && struct s32 { char a; unsigned : 0; } f32(void) {} @@ -140,13 +140,13 @@ struct s32 { char a; unsigned : 0; } f32(void) {} struct s33 { float a; long long : 0; } f33(void) {} // RUN: grep 'define float @f34()' %t && -struct s34 { struct { int : 0 } a; float b; } f34(void) {} +struct s34 { struct { int : 0; } a; float b; } f34(void) {} // RUN: grep 'define i16 @f35()' %t && -struct s35 { struct { int : 0 } a; char b; char c; } f35(void) {} +struct s35 { struct { int : 0; } a; char b; char c; } f35(void) {} // RUN: grep 'define i16 @f36()' %t && -struct s36 { struct { int : 0 } a[2][10]; char b; char c; } f36(void) {} +struct s36 { struct { int : 0; } a[2][10]; char b; char c; } f36(void) {} // RUN: grep 'define float @f37()' %t && struct s37 { float c[1][1]; } f37(void) {} diff --git a/test/CodeGen/x86_64-arguments.c b/test/CodeGen/x86_64-arguments.c index 2e5debe7cb..b28e064d35 100644 --- a/test/CodeGen/x86_64-arguments.c +++ b/test/CodeGen/x86_64-arguments.c @@ -55,4 +55,10 @@ void f10(struct s10 a0) {} // RUN: grep 'define void @f11(.union.anon. noalias sret .agg.result)' %t && union { long double a; float b; } f11() {} +// RUN: grep 'define i64 @f12_0()' %t && +// RUN: grep 'define void @f12_1(i64)' %t && +struct s12 { int a __attribute__((aligned(16))); }; +struct s12 f12_0(void) {} +void f12_1(struct s12 a0) {} + // RUN: true