aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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"
+}