forked from OSchip/llvm-project
[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:
parent
6f93df8105
commit
67528eaacf
|
@ -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) {
|
||||
|
|
|
@ -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]]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue