diff options
author | Chris Lattner <sabre@nondot.org> | 2010-08-23 05:26:13 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-08-23 05:26:13 +0000 |
commit | b6c504b9101251bcb364dd9becbb887c97db27d3 (patch) | |
tree | 8c3f0c18eaae8b39312904ce0f6a397660a55d0b | |
parent | 796788ff212241152afef47c21b077904e188a3f (diff) |
fix rdar://8340348, a miscompile of boost that was exposed by r109848.
That revision started classifying truly empty structs like "Y" and "X"
as being NoClass/NoClass and turning them into 'ignore'. The call code
turns around and allocates space for the ignored argument with
GetUndefRValue. The bug is that GetUndefRValue would return the address
as undef, instead of returning an object with a defined address but
undefined contents.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@111794 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 7 | ||||
-rw-r--r-- | test/CodeGenCXX/x86_64-arguments.cpp | 24 |
2 files changed, 29 insertions, 2 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 0cfd8b6ef9..cf7d01bcd0 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -441,9 +441,12 @@ RValue CodeGenFunction::GetUndefRValue(QualType Ty) { return RValue::getComplex(std::make_pair(U, U)); } + // If this is a use of an undefined aggregate type, the aggregate must have an + // identifiable address. Just because the contents of the value are undefined + // doesn't mean that the address can't be taken and compared. if (hasAggregateLLVMType(Ty)) { - const llvm::Type *LTy = llvm::PointerType::getUnqual(ConvertType(Ty)); - return RValue::getAggregate(llvm::UndefValue::get(LTy)); + llvm::Value *DestPtr = CreateMemTemp(Ty, "undef.agg.tmp"); + return RValue::getAggregate(DestPtr); } return RValue::get(llvm::UndefValue::get(ConvertType(Ty))); diff --git a/test/CodeGenCXX/x86_64-arguments.cpp b/test/CodeGenCXX/x86_64-arguments.cpp index 13f03478f0..cd097680d3 100644 --- a/test/CodeGenCXX/x86_64-arguments.cpp +++ b/test/CodeGenCXX/x86_64-arguments.cpp @@ -76,3 +76,27 @@ namespace PR5179 { return b2.b1.pa; } } + +namespace test5 { + struct Xbase { }; + struct Empty { }; + struct Y; + struct X : public Xbase { + Empty empty; + Y f(); + }; + struct Y : public X { + Empty empty; + }; + X getX(); + int takeY(const Y&, int y); + void g() { + // rdar://8340348 - The temporary for the X object needs to have a defined + // address when passed into X::f as 'this'. + takeY(getX().f(), 42); + } + // CHECK: void @_ZN5test51gEv() + // CHECK: alloca %"struct.test5::Y" + // CHECK: alloca %"struct.test5::X" + // CHECK: alloca %"struct.test5::Y" +} |