[MS ABI] Tolerate invokes of __RTDynamicCast

The pointer returned by __RTDynamicCast must be bitcasted.  However, it
was not expected that __RTDynamicCast would be invoked, resulting in the
bitcast occuring in a different BasicBlock than the invoke.  This caused
a down-stream PHI to get confused about which BasicBlock the incomming
value was from.

This fixes PR25606.

llvm-svn: 253843
This commit is contained in:
David Majnemer 2015-11-23 03:01:14 +00:00
parent 6f93df8105
commit 67528eaacf
2 changed files with 21 additions and 1 deletions

View File

@ -1904,6 +1904,7 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(Address ThisAddr,
"destination type must be a record type!");
Value = CGM.getCXXABI().EmitDynamicCastCall(*this, ThisAddr, SrcRecordTy,
DestTy, DestRecordTy, CastEnd);
CastNotNull = Builder.GetInsertBlock();
}
if (ShouldNullCheckSrcValue) {

View File

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -emit-llvm -O1 -o - -triple=i386-pc-win32 %s | FileCheck %s
// RUN: %clang_cc1 -emit-llvm -O1 -o - -fexceptions -triple=i386-pc-win32 %s | FileCheck %s
struct S { char a; };
struct V { virtual void f(); };
@ -122,3 +122,22 @@ void* test9(B* x) { return dynamic_cast<void*>(x); }
// CHECK: [[RET:%.*]] = phi i8*
// CHECK-NEXT: ret i8* [[RET]]
namespace PR25606 {
struct Cleanup {
~Cleanup();
};
struct S1 { virtual ~S1(); };
struct S2 : virtual S1 {};
struct S3 : S2 {};
S3 *f(S2 &s) {
Cleanup c;
return dynamic_cast<S3 *>(&s);
}
// CHECK-LABEL: define %"struct.PR25606::S3"* @"\01?f@PR25606@@YAPAUS3@1@AAUS2@1@@Z"(
// CHECK: [[CALL:%.*]] = invoke i8* @__RTDynamicCast
// CHECK: [[BC:%.*]] = bitcast i8* [[CALL]] to %"struct.PR25606::S3"*
// CHECK: call x86_thiscallcc void @"\01??_DCleanup@PR25606@@QAE@XZ"(
// CHECK: ret %"struct.PR25606::S3"* [[BC]]
}