From 0e97bcbee9d5f7735edecbccfb5031a2f065f286 Mon Sep 17 00:00:00 2001 From: Marcin Swiderski Date: Fri, 1 Oct 2010 01:46:52 +0000 Subject: [PATCH] Added generating CFGAutomaticObjDtors for exception variable in catch statement. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115266 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/CFG.cpp | 12 ++++++ test/Analysis/auto-obj-dtors-cfg-output.cpp | 41 +++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index ac49ca52ca..a60c3a6b01 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -2154,6 +2154,18 @@ CFGBlock* CFGBuilder::VisitCXXCatchStmt(CXXCatchStmt* CS) { // CXXCatchStmt are treated like labels, so they are the first statement in a // block. + // Save local scope position because in case of exception variable ScopePos + // won't be restored when traversing AST. + SaveAndRestore save_scope_pos(ScopePos); + + // Create local scope for possible exception variable. + // Store scope position. Add implicit destructor. + if (VarDecl* VD = CS->getExceptionDecl()) { + LocalScope::const_iterator BeginScopePos = ScopePos; + addLocalScopeForVarDecl(VD); + addAutomaticObjDtors(ScopePos, BeginScopePos, CS); + } + if (CS->getHandlerBlock()) addStmt(CS->getHandlerBlock()); diff --git a/test/Analysis/auto-obj-dtors-cfg-output.cpp b/test/Analysis/auto-obj-dtors-cfg-output.cpp index 2024e62ab6..8a6c55b60b 100644 --- a/test/Analysis/auto-obj-dtors-cfg-output.cpp +++ b/test/Analysis/auto-obj-dtors-cfg-output.cpp @@ -138,6 +138,18 @@ void test_for_jumps() { A f; } +void test_catch_const_ref() { + try { + } catch (const A& e) { + } +} + +void test_catch_copy() { + try { + } catch (A e) { + } +} + // CHECK: [ B2 (ENTRY) ] // CHECK: Predecessors (0): // CHECK: Successors (1): B1 @@ -726,3 +738,32 @@ void test_for_jumps() { // CHECK: [ B0 (EXIT) ] // CHECK: Predecessors (2): B1 B5 // CHECK: Successors (0): +// CHECK: [ B3 (ENTRY) ] +// CHECK: Predecessors (0): +// CHECK: Successors (1): B0 +// CHECK: [ B1 ] +// CHECK: T: try ... +// CHECK: Predecessors (0): +// CHECK: Successors (2): B2 B0 +// CHECK: [ B2 ] +// CHECK: catch (const A &e): +// CHECK: Predecessors (1): B1 +// CHECK: Successors (1): B0 +// CHECK: [ B0 (EXIT) ] +// CHECK: Predecessors (3): B2 B1 B3 +// CHECK: Successors (0): +// CHECK: [ B3 (ENTRY) ] +// CHECK: Predecessors (0): +// CHECK: Successors (1): B0 +// CHECK: [ B1 ] +// CHECK: T: try ... +// CHECK: Predecessors (0): +// CHECK: Successors (2): B2 B0 +// CHECK: [ B2 ] +// CHECK: catch (A e): +// CHECK: 1: .~A() (Implicit destructor) +// CHECK: Predecessors (1): B1 +// CHECK: Successors (1): B0 +// CHECK: [ B0 (EXIT) ] +// CHECK: Predecessors (3): B2 B1 B3 +// CHECK: Successors (0):