From: Marcin Swiderski Date: Fri, 1 Oct 2010 00:52:17 +0000 (+0000) Subject: Added generating CFGAutomaticObjDtors for condition variable and implicit scopes... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=04e046cbf7153fc261d730d460f081322d5c42f6;p=clang Added generating CFGAutomaticObjDtors for condition variable and implicit scopes in if statement. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@115256 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 33e0ff94c2..fd8b009aba 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -1136,6 +1136,18 @@ CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) { // middle of a block, we stop processing that block. That block is then the // implicit successor for the "then" and "else" clauses. + // Save local scope position because in case of condition variable ScopePos + // won't be restored when traversing AST. + SaveAndRestore save_scope_pos(ScopePos); + + // Create local scope for possible condition variable. + // Store scope position. Add implicit destructor. + if (VarDecl* VD = I->getConditionVariable()) { + LocalScope::const_iterator BeginScopePos = ScopePos; + addLocalScopeForVarDecl(VD); + addAutomaticObjDtors(ScopePos, BeginScopePos, I); + } + // The block we were proccessing is now finished. Make it the successor // block. if (Block) { @@ -1153,6 +1165,12 @@ CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) { // NULL out Block so that the recursive call to Visit will // create a new basic block. Block = NULL; + + // If branch is not a compound statement create implicit scope + // and add destructors. + if (!isa(Else)) + addLocalScopeAndDtors(Else); + ElseBlock = addStmt(Else); if (!ElseBlock) // Can occur when the Else body has all NullStmts. @@ -1170,6 +1188,12 @@ CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) { assert(Then); SaveAndRestore sv(Succ); Block = NULL; + + // If branch is not a compound statement create implicit scope + // and add destructors. + if (!isa(Then)) + addLocalScopeAndDtors(Then); + ThenBlock = addStmt(Then); if (!ThenBlock) { diff --git a/test/Analysis/auto-obj-dtors-cfg-output.cpp b/test/Analysis/auto-obj-dtors-cfg-output.cpp index d3896c5112..ce3454d008 100644 --- a/test/Analysis/auto-obj-dtors-cfg-output.cpp +++ b/test/Analysis/auto-obj-dtors-cfg-output.cpp @@ -44,6 +44,27 @@ l1: A c; } +void test_if_implicit_scope() { + A a; + if (A b = a) + A c; + else A c; +} + +void test_if_jumps() { + A a; + if (A b = a) { + A c; + if (UV) return; + A d; + } else { + A c; + if (UV) return; + A d; + } + A e; +} + // CHECK: [ B2 (ENTRY) ] // CHECK: Predecessors (0): // CHECK: Successors (1): B1 @@ -149,3 +170,98 @@ l1: // CHECK: [ B0 (EXIT) ] // CHECK: Predecessors (1): B1 // CHECK: Successors (0): +// CHECK: [ B5 (ENTRY) ] +// CHECK: Predecessors (0): +// CHECK: Successors (1): B4 +// CHECK: [ B1 ] +// CHECK: 1: [B4.3].~A() (Implicit destructor) +// CHECK: 2: [B4.1].~A() (Implicit destructor) +// CHECK: Predecessors (2): B2 B3 +// CHECK: Successors (1): B0 +// CHECK: [ B2 ] +// CHECK: 1: A c; +// CHECK: 2: [B2.1].~A() (Implicit destructor) +// CHECK: Predecessors (1): B4 +// CHECK: Successors (1): B1 +// CHECK: [ B3 ] +// CHECK: 1: A c; +// CHECK: 2: [B3.1].~A() (Implicit destructor) +// CHECK: Predecessors (1): B4 +// CHECK: Successors (1): B1 +// CHECK: [ B4 ] +// CHECK: 1: A a; +// CHECK: 2: a +// CHECK: 3: if ([B4.5]) +// CHECK: [B3.1]else +// CHECK: [B2.1] 4: b.operator int() +// CHECK: 5: [B4.4] +// CHECK: T: if [B4.5] +// CHECK: Predecessors (1): B5 +// CHECK: Successors (2): B3 B2 +// CHECK: [ B0 (EXIT) ] +// CHECK: Predecessors (1): B1 +// CHECK: Successors (0): +// CHECK: [ B9 (ENTRY) ] +// CHECK: Predecessors (0): +// CHECK: Successors (1): B8 +// CHECK: [ B1 ] +// CHECK: 1: [B8.3].~A() (Implicit destructor) +// CHECK: 2: A e; +// CHECK: 3: [B1.2].~A() (Implicit destructor) +// CHECK: 4: [B8.1].~A() (Implicit destructor) +// CHECK: Predecessors (2): B2 B5 +// CHECK: Successors (1): B0 +// CHECK: [ B2 ] +// CHECK: 1: A d; +// CHECK: 2: [B2.1].~A() (Implicit destructor) +// CHECK: 3: [B4.1].~A() (Implicit destructor) +// CHECK: Predecessors (1): B4 +// CHECK: Successors (1): B1 +// CHECK: [ B3 ] +// CHECK: 1: return; +// CHECK: 2: [B4.1].~A() (Implicit destructor) +// CHECK: 3: [B8.3].~A() (Implicit destructor) +// CHECK: 4: [B8.1].~A() (Implicit destructor) +// CHECK: Predecessors (1): B4 +// CHECK: Successors (1): B0 +// CHECK: [ B4 ] +// CHECK: 1: A c; +// CHECK: 2: UV +// CHECK: T: if [B4.2] +// CHECK: Predecessors (1): B8 +// CHECK: Successors (2): B3 B2 +// CHECK: [ B5 ] +// CHECK: 1: A d; +// CHECK: 2: [B5.1].~A() (Implicit destructor) +// CHECK: 3: [B7.1].~A() (Implicit destructor) +// CHECK: Predecessors (1): B7 +// CHECK: Successors (1): B1 +// CHECK: [ B6 ] +// CHECK: 1: return; +// CHECK: 2: [B7.1].~A() (Implicit destructor) +// CHECK: 3: [B8.3].~A() (Implicit destructor) +// CHECK: 4: [B8.1].~A() (Implicit destructor) +// CHECK: Predecessors (1): B7 +// CHECK: Successors (1): B0 +// CHECK: [ B7 ] +// CHECK: 1: A c; +// CHECK: 2: UV +// CHECK: T: if [B7.2] +// CHECK: Predecessors (1): B8 +// CHECK: Successors (2): B6 B5 +// CHECK: [ B8 ] +// CHECK: 1: A a; +// CHECK: 2: a +// CHECK: 3: if ([B8.5]) { +// CHECK: [B7.1] if ([B7.2]) +// CHECK: [B6.1][B5.1]} else { +// CHECK: [B4.1] if ([B4.2]) +// CHECK: [B3.1][B2.1]} +// CHECK: 4: b.operator int() +// CHECK: 5: [B8.4] +// CHECK: T: if [B8.5] +// CHECK: Predecessors (1): B9 +// CHECK: Successors (2): B7 B4 +// CHECK: [ B0 (EXIT) ] +// CHECK: Predecessors (3): B1 B3 B6 +// CHECK: Successors (0):