forked from OSchip/llvm-project
Fix crash in ObjC codegen introduced with 5ab6ee7599
5ab6ee7599
assumed that if `RValue::isScalar()` returns true then `RValue::getScalarVal` will return a valid value. This is not the case when the return value is `void` and so void message returns would crash if they hit this path. This is triggered only for cases where the nil-handling path needs to do something non-trivial (destroy arguments that should be consumed by the callee).
Reviewed By: triplef
Differential Revision: https://reviews.llvm.org/D123898
This commit is contained in:
parent
0708771cce
commit
94c3b16978
|
@ -2837,11 +2837,13 @@ CGObjCGNU::GenerateMessageSend(CodeGenFunction &CGF,
|
||||||
// Enter the continuation block and emit a phi if required.
|
// Enter the continuation block and emit a phi if required.
|
||||||
CGF.EmitBlock(continueBB);
|
CGF.EmitBlock(continueBB);
|
||||||
if (msgRet.isScalar()) {
|
if (msgRet.isScalar()) {
|
||||||
llvm::Value *v = msgRet.getScalarVal();
|
// If the return type is void, do nothing
|
||||||
llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
|
if (llvm::Value *v = msgRet.getScalarVal()) {
|
||||||
phi->addIncoming(v, nonNilPathBB);
|
llvm::PHINode *phi = Builder.CreatePHI(v->getType(), 2);
|
||||||
phi->addIncoming(CGM.EmitNullConstant(ResultType), nilPathBB);
|
phi->addIncoming(v, nonNilPathBB);
|
||||||
msgRet = RValue::get(phi);
|
phi->addIncoming(CGM.EmitNullConstant(ResultType), nilPathBB);
|
||||||
|
msgRet = RValue::get(phi);
|
||||||
|
}
|
||||||
} else if (msgRet.isAggregate()) {
|
} else if (msgRet.isAggregate()) {
|
||||||
// Aggregate zeroing is handled in nilCleanupBB when it's required.
|
// Aggregate zeroing is handled in nilCleanupBB when it's required.
|
||||||
} else /* isComplex() */ {
|
} else /* isComplex() */ {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
// RUN: %clang_cc1 -triple x86_64-unknow-windows-msvc -S -emit-llvm -fobjc-runtime=gnustep-2.0 -o - %s
|
||||||
|
|
||||||
|
// Regression test. Ensure that C++ arguments with non-trivial destructors
|
||||||
|
// don't crash the compiler.
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
int a;
|
||||||
|
~X();
|
||||||
|
};
|
||||||
|
|
||||||
|
@protocol Y
|
||||||
|
- (void)foo: (X)bar;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
void test(id<Y> obj)
|
||||||
|
{
|
||||||
|
X a{12};
|
||||||
|
[obj foo: a];
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue