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
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)));
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"
+}