]> granicus.if.org Git - clang/commitdiff
[WinEH] Annotate calls to __RTtypeid with a funclet bundle
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 26 Jan 2016 23:14:47 +0000 (23:14 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 26 Jan 2016 23:14:47 +0000 (23:14 +0000)
Clang's CodeGen has several paths which end up invoking or calling a
function. The one that we used for calls to __RTtypeid did not
appropriately annotate the call with a funclet bundle.

This fixes PR26329.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@258877 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCall.cpp
test/CodeGenCXX/microsoft-abi-typeid.cpp

index b589ae3f88fe6101cdec0d6c495383f60db73d74..5bd452e1c97f040daae0775bfa7061891a0c9a79 100644 (file)
@@ -3121,13 +3121,16 @@ CodeGenFunction::EmitCallOrInvoke(llvm::Value *Callee,
                                   ArrayRef<llvm::Value *> Args,
                                   const Twine &Name) {
   llvm::BasicBlock *InvokeDest = getInvokeDest();
+  SmallVector<llvm::OperandBundleDef, 1> BundleList;
+  getBundlesForFunclet(Callee, CurrentFuncletPad, BundleList);
 
   llvm::Instruction *Inst;
   if (!InvokeDest)
-    Inst = Builder.CreateCall(Callee, Args, Name);
+    Inst = Builder.CreateCall(Callee, Args, BundleList, Name);
   else {
     llvm::BasicBlock *ContBB = createBasicBlock("invoke.cont");
-    Inst = Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, Name);
+    Inst = Builder.CreateInvoke(Callee, ContBB, InvokeDest, Args, BundleList,
+                                Name);
     EmitBlock(ContBB);
   }
 
index 60c31ab4706c11018a094f04719fdb5b4cc8ca73..d73f8483a713953c6e1effdf6572a685ae777b88 100644 (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 - -triple=i386-pc-win32 %s -fexceptions -fcxx-exceptions | FileCheck %s
 
 struct type_info;
 namespace std { using ::type_info; }
@@ -49,3 +49,22 @@ const std::type_info* test5_typeid() { return &typeid(v); }
 // CHECK:        [[RT:%.*]] = tail call i8* @__RTtypeid(i8* bitcast (%struct.V* @"\01?v@@3UV@@A" to i8*))
 // CHECK-NEXT:   [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info*
 // CHECK-NEXT:   ret %struct.type_info* [[RET]]
+
+namespace PR26329 {
+struct Polymorphic {
+  virtual ~Polymorphic();
+};
+
+void f(const Polymorphic &poly) {
+  try {
+    throw;
+  } catch (...) {
+    Polymorphic cleanup;
+    typeid(poly);
+  }
+}
+// CHECK-LABEL: define void @"\01?f@PR26329@@YAXABUPolymorphic@1@@Z"(
+// CHECK: %[[cs:.*]] = catchswitch within none [label %{{.*}}] unwind to caller
+// CHECK: %[[cp:.*]] = catchpad within %[[cs]] [i8* null, i32 64, i8* null]
+// CHECK: invoke i8* @__RTtypeid(i8* {{.*}}) [ "funclet"(token %[[cp]]) ]
+}