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.*}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits