aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-08-23 05:26:13 +0000
committerChris Lattner <sabre@nondot.org>2010-08-23 05:26:13 +0000
commitb6c504b9101251bcb364dd9becbb887c97db27d3 (patch)
tree8c3f0c18eaae8b39312904ce0f6a397660a55d0b
parent796788ff212241152afef47c21b077904e188a3f (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.cpp7
-rw-r--r--test/CodeGenCXX/x86_64-arguments.cpp24
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"
+}