| // RUN: %clang_analyze_cc1 %s \ |
| // RUN: -analyzer-checker=debug.DumpDominators \ |
| // RUN: -analyzer-checker=debug.DumpPostDominators \ |
| // RUN: -analyzer-checker=debug.DumpControlDependencies \ |
| // RUN: 2>&1 | FileCheck %s |
| |
| // Test the DominatorsTree implementation with various control flows |
| int test1() |
| { |
| int x = 6; |
| int y = x/2; |
| int z; |
| |
| while(y > 0) { |
| if(y < x) { |
| x = x/y; |
| y = y-1; |
| }else{ |
| z = x - y; |
| } |
| x = x - 1; |
| x = x - 1; |
| } |
| z = x+y; |
| z = 3; |
| return 0; |
| } |
| |
| // [B9 (ENTRY)] -> [B8] -> [B7] -> [B6] -> [B5] -> [B3] -> [B2] |
| // |\ \ / / |
| // | \ ---> [B4] ---> / |
| // | <--------------------------- |
| // V |
| // [B1] -> [B0 (EXIT)] |
| |
| // CHECK: Control dependencies (Node#,Dependency#): |
| // CHECK-NEXT: (2,7) |
| // CHECK-NEXT: (3,7) |
| // CHECK-NEXT: (4,6) |
| // CHECK-NEXT: (4,7) |
| // CHECK-NEXT: (5,6) |
| // CHECK-NEXT: (5,7) |
| // CHECK-NEXT: (6,7) |
| // CHECK-NEXT: (7,7) |
| // CHECK-NEXT: Immediate dominance tree (Node#,IDom#): |
| // CHECK-NEXT: (0,1) |
| // CHECK-NEXT: (1,7) |
| // CHECK-NEXT: (2,3) |
| // CHECK-NEXT: (3,6) |
| // CHECK-NEXT: (4,6) |
| // CHECK-NEXT: (5,6) |
| // CHECK-NEXT: (6,7) |
| // CHECK-NEXT: (7,8) |
| // CHECK-NEXT: (8,9) |
| // CHECK-NEXT: (9,9) |
| // CHECK-NEXT: Immediate post dominance tree (Node#,IDom#): |
| // CHECK-NEXT: (0,0) |
| // CHECK-NEXT: (1,0) |
| // CHECK-NEXT: (2,7) |
| // CHECK-NEXT: (3,2) |
| // CHECK-NEXT: (4,3) |
| // CHECK-NEXT: (5,3) |
| // CHECK-NEXT: (6,3) |
| // CHECK-NEXT: (7,1) |
| // CHECK-NEXT: (8,7) |
| // CHECK-NEXT: (9,8) |
| |
| int test2() |
| { |
| int x,y,z; |
| |
| x = 10; y = 100; |
| if(x > 0){ |
| y = 1; |
| }else{ |
| while(x<=0){ |
| x++; |
| y++; |
| } |
| } |
| z = y; |
| |
| return 0; |
| } |
| |
| // <------------- |
| // / \ |
| // -----------> [B4] -> [B3] -> [B2] |
| // / | |
| // / V |
| // [B7 (ENTRY)] -> [B6] -> [B5] -> [B1] -> [B0 (EXIT)] |
| |
| // CHECK: Control dependencies (Node#,Dependency#): |
| // CHECK-NEXT: (2,4) |
| // CHECK-NEXT: (2,6) |
| // CHECK-NEXT: (3,4) |
| // CHECK-NEXT: (3,6) |
| // CHECK-NEXT: (4,6) |
| // CHECK-NEXT: (4,4) |
| // CHECK-NEXT: (5,6) |
| // CHECK-NEXT: Immediate dominance tree (Node#,IDom#): |
| // CHECK-NEXT: (0,1) |
| // CHECK-NEXT: (1,6) |
| // CHECK-NEXT: (2,3) |
| // CHECK-NEXT: (3,4) |
| // CHECK-NEXT: (4,6) |
| // CHECK-NEXT: (5,6) |
| // CHECK-NEXT: (6,7) |
| // CHECK-NEXT: (7,7) |
| // CHECK-NEXT: Immediate post dominance tree (Node#,IDom#): |
| // CHECK-NEXT: (0,0) |
| // CHECK-NEXT: (1,0) |
| // CHECK-NEXT: (2,4) |
| // CHECK-NEXT: (3,2) |
| // CHECK-NEXT: (4,1) |
| // CHECK-NEXT: (5,1) |
| // CHECK-NEXT: (6,1) |
| // CHECK-NEXT: (7,6) |
| |
| int test3() |
| { |
| int x,y,z; |
| |
| x = y = z = 1; |
| if(x>0) { |
| while(x>=0){ |
| while(y>=x) { |
| x = x-1; |
| y = y/2; |
| } |
| } |
| } |
| z = y; |
| |
| return 0; |
| } |
| |
| // <- [B2] <- |
| // / \ |
| // [B8 (ENTRY)] -> [B7] -> [B6] ---> [B5] -> [B4] -> [B3] |
| // \ | \ / |
| // \ | <------------- |
| // \ \ |
| // --------> [B1] -> [B0 (EXIT)] |
| |
| // CHECK: Control dependencies (Node#,Dependency#): |
| // CHECK-NEXT: (2,6) |
| // CHECK-NEXT: (2,7) |
| // CHECK-NEXT: (3,5) |
| // CHECK-NEXT: (3,6) |
| // CHECK-NEXT: (3,7) |
| // CHECK-NEXT: (4,5) |
| // CHECK-NEXT: (4,6) |
| // CHECK-NEXT: (4,7) |
| // CHECK-NEXT: (5,6) |
| // CHECK-NEXT: (5,5) |
| // CHECK-NEXT: (5,7) |
| // CHECK-NEXT: (6,7) |
| // CHECK-NEXT: (6,6) |
| // CHECK-NEXT: Immediate dominance tree (Node#,IDom#): |
| // CHECK-NEXT: (0,1) |
| // CHECK-NEXT: (1,7) |
| // CHECK-NEXT: (2,5) |
| // CHECK-NEXT: (3,4) |
| // CHECK-NEXT: (4,5) |
| // CHECK-NEXT: (5,6) |
| // CHECK-NEXT: (6,7) |
| // CHECK-NEXT: (7,8) |
| // CHECK-NEXT: (8,8) |
| // CHECK-NEXT: Immediate post dominance tree (Node#,IDom#): |
| // CHECK-NEXT: (0,0) |
| // CHECK-NEXT: (1,0) |
| // CHECK-NEXT: (2,6) |
| // CHECK-NEXT: (3,5) |
| // CHECK-NEXT: (4,3) |
| // CHECK-NEXT: (5,2) |
| // CHECK-NEXT: (6,1) |
| // CHECK-NEXT: (7,1) |
| // CHECK-NEXT: (8,7) |
| |
| int test4() |
| { |
| int y = 3; |
| while(y > 0) { |
| if(y < 3) { |
| while(y>0) |
| y ++; |
| }else{ |
| while(y<10) |
| y ++; |
| } |
| } |
| return 0; |
| } |
| |
| // <---------------------------------- |
| // / <----------------- \ |
| // / / \ \ |
| // [B12 (ENTRY)] -> [B11] -> [B10]-> [B9] -> [B8] ---> [B7] -> [B6] | |
| // | \ \ / |
| // | \ -----> [B2] --------/ |
| // | \ / |
| // | -> [B5] -> [B4] -> [B3] |
| // | \ / |
| // | <------------ |
| // \ |
| // -> [B1] -> [B0 (EXIT)] |
| |
| // CHECK: Control dependencies (Node#,Dependency#): |
| // CHECK-NEXT: (2,10) |
| // CHECK-NEXT: (3,5) |
| // CHECK-NEXT: (3,9) |
| // CHECK-NEXT: (3,10) |
| // CHECK-NEXT: (4,5) |
| // CHECK-NEXT: (4,9) |
| // CHECK-NEXT: (4,10) |
| // CHECK-NEXT: (5,9) |
| // CHECK-NEXT: (5,5) |
| // CHECK-NEXT: (5,10) |
| // CHECK-NEXT: (6,8) |
| // CHECK-NEXT: (6,9) |
| // CHECK-NEXT: (6,10) |
| // CHECK-NEXT: (7,8) |
| // CHECK-NEXT: (7,9) |
| // CHECK-NEXT: (7,10) |
| // CHECK-NEXT: (8,9) |
| // CHECK-NEXT: (8,8) |
| // CHECK-NEXT: (8,10) |
| // CHECK-NEXT: (9,10) |
| // CHECK-NEXT: (10,10) |
| // CHECK-NEXT: Immediate dominance tree (Node#,IDom#): |
| // CHECK-NEXT: (0,1) |
| // CHECK-NEXT: (1,10) |
| // CHECK-NEXT: (2,9) |
| // CHECK-NEXT: (3,4) |
| // CHECK-NEXT: (4,5) |
| // CHECK-NEXT: (5,9) |
| // CHECK-NEXT: (6,7) |
| // CHECK-NEXT: (7,8) |
| // CHECK-NEXT: (8,9) |
| // CHECK-NEXT: (9,10) |
| // CHECK-NEXT: (10,11) |
| // CHECK-NEXT: (11,12) |
| // CHECK-NEXT: (12,12) |
| // CHECK-NEXT: Immediate post dominance tree (Node#,IDom#): |
| // CHECK-NEXT: (0,0) |
| // CHECK-NEXT: (1,0) |
| // CHECK-NEXT: (2,10) |
| // CHECK-NEXT: (3,5) |
| // CHECK-NEXT: (4,3) |
| // CHECK-NEXT: (5,2) |
| // CHECK-NEXT: (6,8) |
| // CHECK-NEXT: (7,6) |
| // CHECK-NEXT: (8,2) |
| // CHECK-NEXT: (9,2) |
| // CHECK-NEXT: (10,1) |
| // CHECK-NEXT: (11,10) |
| // CHECK-NEXT: (12,11) |
| |
| int test5() |
| { |
| int x,y,z,a,b,c; |
| x = 1; |
| y = 2; |
| z = 3; |
| a = 4; |
| b = 5; |
| c = 6; |
| if ( x < 10 ) { |
| if ( y < 10 ) { |
| if ( z < 10 ) { |
| x = 4; |
| } else { |
| x = 5; |
| } |
| a = 10; |
| } else { |
| x = 6; |
| } |
| b = 10; |
| } else { |
| x = 7; |
| } |
| c = 11; |
| return 0; |
| } |
| |
| // [B0 (EXIT)] <-- |
| // \ |
| // [B11 (ENTY)] -> [B10] -> [B9] -> [B8] -> [B7] -> [B5] -> [B3] -> [B1] |
| // | | | / / / |
| // | | V / / / |
| // | V [B6] --> / / |
| // V [B4] -----------------> / |
| // [B2]---------------------------------> |
| |
| // CHECK: Control dependencies (Node#,Dependency#): |
| // CHECK-NEXT: (2,10) |
| // CHECK-NEXT: (3,10) |
| // CHECK-NEXT: (4,9) |
| // CHECK-NEXT: (4,10) |
| // CHECK-NEXT: (5,9) |
| // CHECK-NEXT: (5,10) |
| // CHECK-NEXT: (6,8) |
| // CHECK-NEXT: (6,9) |
| // CHECK-NEXT: (6,10) |
| // CHECK-NEXT: (7,8) |
| // CHECK-NEXT: (7,9) |
| // CHECK-NEXT: (7,10) |
| // CHECK-NEXT: (8,9) |
| // CHECK-NEXT: (8,10) |
| // CHECK-NEXT: (9,10) |
| // CHECK-NEXT: Immediate dominance tree (Node#,IDom#): |
| // CHECK-NEXT: (0,1) |
| // CHECK-NEXT: (1,10) |
| // CHECK-NEXT: (2,10) |
| // CHECK-NEXT: (3,9) |
| // CHECK-NEXT: (4,9) |
| // CHECK-NEXT: (5,8) |
| // CHECK-NEXT: (6,8) |
| // CHECK-NEXT: (7,8) |
| // CHECK-NEXT: (8,9) |
| // CHECK-NEXT: (9,10) |
| // CHECK-NEXT: (10,11) |
| // CHECK-NEXT: (11,11) |
| // CHECK-NEXT: Immediate post dominance tree (Node#,IDom#): |
| // CHECK-NEXT: (0,0) |
| // CHECK-NEXT: (1,0) |
| // CHECK-NEXT: (2,1) |
| // CHECK-NEXT: (3,1) |
| // CHECK-NEXT: (4,3) |
| // CHECK-NEXT: (5,3) |
| // CHECK-NEXT: (6,5) |
| // CHECK-NEXT: (7,5) |
| // CHECK-NEXT: (8,5) |
| // CHECK-NEXT: (9,3) |
| // CHECK-NEXT: (10,1) |
| // CHECK-NEXT: (11,10) |