r247075 - Collect SEH captures in a set instead of a vector to avoid

John McCall via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 8 14:15:22 PDT 2015


Author: rjmccall
Date: Tue Sep  8 16:15:22 2015
New Revision: 247075

URL: http://llvm.org/viewvc/llvm-project?rev=247075&view=rev
Log:
Collect SEH captures in a set instead of a vector to avoid
doing redundant work if a variable is used multiple times.

Fixes PR24751.

Modified:
    cfe/trunk/lib/CodeGen/CGException.cpp
    cfe/trunk/test/CodeGen/exceptions-seh.c

Modified: cfe/trunk/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=247075&r1=247074&r2=247075&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGException.cpp Tue Sep  8 16:15:22 2015
@@ -1433,7 +1433,7 @@ namespace {
 struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
   CodeGenFunction &ParentCGF;
   const VarDecl *ParentThis;
-  SmallVector<const VarDecl *, 4> Captures;
+  llvm::SmallSetVector<const VarDecl *, 4> Captures;
   Address SEHCodeSlot = Address::invalid();
   CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)
       : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
@@ -1454,17 +1454,17 @@ struct CaptureFinder : ConstStmtVisitor<
   void VisitDeclRefExpr(const DeclRefExpr *E) {
     // If this is already a capture, just make sure we capture 'this'.
     if (E->refersToEnclosingVariableOrCapture()) {
-      Captures.push_back(ParentThis);
+      Captures.insert(ParentThis);
       return;
     }
 
     const auto *D = dyn_cast<VarDecl>(E->getDecl());
     if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
-      Captures.push_back(D);
+      Captures.insert(D);
   }
 
   void VisitCXXThisExpr(const CXXThisExpr *E) {
-    Captures.push_back(ParentThis);
+    Captures.insert(ParentThis);
   }
 
   void VisitCallExpr(const CallExpr *E) {

Modified: cfe/trunk/test/CodeGen/exceptions-seh.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh.c?rev=247075&r1=247074&r2=247075&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/exceptions-seh.c (original)
+++ cfe/trunk/test/CodeGen/exceptions-seh.c Tue Sep  8 16:15:22 2015
@@ -230,4 +230,34 @@ int except_return(void) {
 // CHECK: %[[r:[^ ]*]] = load i32, i32* %[[rv]]
 // CHECK: ret i32 %[[r]]
 
+
+// PR 24751: don't assert if a variable is used twice in a __finally block.
+// Also, make sure we don't do redundant work to capture/project it.
+void finally_capture_twice(int x) {
+  __try {
+  } __finally {
+    int y = x;
+    int z = x;
+  }
+}
+//  
+// CHECK-LABEL: define void @finally_capture_twice(
+// CHECK:         [[X:%.*]] = alloca i32, align 4
+// CHECK:         call void (...) @llvm.localescape(i32* [[X]])
+// CHECK-NEXT:    store i32 {{.*}}, i32* [[X]], align 4
+// CHECK-NEXT:    [[LOCAL:%.*]] = call i8* @llvm.localaddress()
+// CHECK-NEXT:    call void [[FINALLY:@.*]](i8{{ zeroext | }}0, i8* [[LOCAL]])
+// CHECK:       define internal void [[FINALLY]](
+// CHECK:         [[LOCAL:%.*]] = call i8* @llvm.localrecover(
+// CHECK:         [[X:%.*]] = bitcast i8* [[LOCAL]] to i32*
+// CHECK-NEXT:    [[Y:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    [[Z:%.*]] = alloca i32, align 4
+// CHECK-NEXT:    store i8*
+// CHECK-NEXT:    store i8
+// CHECK-NEXT:    [[T0:%.*]] = load i32, i32* [[X]], align 4
+// CHECK-NEXT:    store i32 [[T0]], i32* [[Y]], align 4
+// CHECK-NEXT:    [[T0:%.*]] = load i32, i32* [[X]], align 4
+// CHECK-NEXT:    store i32 [[T0]], i32* [[Z]], align 4
+// CHECK-NEXT:    ret void
+
 // CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} }




More information about the cfe-commits mailing list