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