diff options
-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" +} |