| // RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -analyzer-config cfg-loopexit=true %s > %t 2>&1 | |
| // RUN: FileCheck --input-file=%t %s | |
| // CHECK: [B6 (ENTRY)] | |
| // CHECK-NEXT: Succs (1): B5 | |
| // CHECK: [B1] | |
| // CHECK-NEXT: 1: ForStmt (LoopExit) | |
| // CHECK-NEXT: 2: return; | |
| // CHECK-NEXT: Preds (1): B4 | |
| // CHECK-NEXT: Succs (1): B0 | |
| // CHECK: [B2] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B2.1]++ | |
| // CHECK-NEXT: Preds (1): B3 | |
| // CHECK-NEXT: Succs (1): B4 | |
| // CHECK: [B3] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B3.1]++ | |
| // CHECK-NEXT: Preds (1): B4 | |
| // CHECK-NEXT: Succs (1): B2 | |
| // CHECK: [B4] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 3: 12 | |
| // CHECK-NEXT: 4: [B4.2] < [B4.3] | |
| // CHECK-NEXT: T: for (...; [B4.4]; ...) | |
| // CHECK-NEXT: Preds (2): B2 B5 | |
| // CHECK-NEXT: Succs (2): B3 B1 | |
| // CHECK: [B5] | |
| // CHECK-NEXT: 1: 0 | |
| // CHECK-NEXT: 2: int i = 0; | |
| // CHECK-NEXT: Preds (1): B6 | |
| // CHECK-NEXT: Succs (1): B4 | |
| // CHECK: [B0 (EXIT)] | |
| // CHECK-NEXT: Preds (1): B1 | |
| void check_forloop1() { | |
| for (int i = 0; i < 12; i++) { | |
| i++; | |
| } | |
| return; | |
| } | |
| // CHECK: [B4 (ENTRY)] | |
| // CHECK-NEXT: Succs (1): B3 | |
| // CHECK: [B1] | |
| // CHECK-NEXT: 1: ForStmt (LoopExit) | |
| // CHECK-NEXT: Succs (1): B0 | |
| // CHECK: [B2] | |
| // CHECK-NEXT: Preds (1): B3 | |
| // CHECK-NEXT: Succs (1): B3 | |
| // CHECK: [B3] | |
| // CHECK-NEXT: T: for (; ; ) | |
| // CHECK-NEXT: Preds (2): B2 B4 | |
| // CHECK-NEXT: Succs (2): B2 NULL | |
| // CHECK: [B0 (EXIT)] | |
| // CHECK-NEXT: Preds (1): B1 | |
| void check_forloop2() { | |
| for (;;) | |
| ; | |
| } | |
| // CHECK: [B5 (ENTRY)] | |
| // CHECK-NEXT: Succs (1): B4 | |
| // CHECK: [B1] | |
| // CHECK-NEXT: 1: WhileStmt (LoopExit) | |
| // CHECK-NEXT: Succs (1): B0 | |
| // CHECK: [B2] | |
| // CHECK-NEXT: Preds (1): B3 | |
| // CHECK-NEXT: Succs (1): B4 | |
| // CHECK: [B3] | |
| // CHECK-NEXT: 1: int i; | |
| // CHECK-NEXT: Preds (1): B4 | |
| // CHECK-NEXT: Succs (1): B2 | |
| // CHECK: [B4] | |
| // CHECK-NEXT: 1: true | |
| // CHECK-NEXT: T: while [B4.1] | |
| // CHECK-NEXT: Preds (2): B2 B5 | |
| // CHECK-NEXT: Succs (2): B3 NULL | |
| // CHECK: [B0 (EXIT)] | |
| // CHECK-NEXT: Preds (1): B1 | |
| void check_while1() { | |
| while (true) { | |
| int i; | |
| } | |
| } | |
| // CHECK: [B5 (ENTRY)] | |
| // CHECK-NEXT: Succs (1): B4 | |
| // CHECK: [B1] | |
| // CHECK-NEXT: 1: WhileStmt (LoopExit) | |
| // CHECK-NEXT: 2: 2 | |
| // CHECK-NEXT: 3: int k = 2; | |
| // CHECK-NEXT: 4: return; | |
| // CHECK-NEXT: Preds (1): B3 | |
| // CHECK-NEXT: Succs (1): B0 | |
| // CHECK: [B2] | |
| // CHECK-NEXT: Preds (1): B3 | |
| // CHECK-NEXT: Succs (1): B3 | |
| // CHECK: [B3] | |
| // CHECK-NEXT: 1: l | |
| // CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 3: 42 | |
| // CHECK-NEXT: 4: [B3.2] < [B3.3] | |
| // CHECK-NEXT: T: while [B3.4] | |
| // CHECK-NEXT: Preds (2): B2 B4 | |
| // CHECK-NEXT: Succs (2): B2 B1 | |
| // CHECK: [B4] | |
| // CHECK-NEXT: 1: int l; | |
| // CHECK-NEXT: Preds (1): B5 | |
| // CHECK-NEXT: Succs (1): B3 | |
| // CHECK: [B0 (EXIT)] | |
| // CHECK-NEXT: Preds (1): B1 | |
| void check_while2() { | |
| int l; | |
| while (l < 42) | |
| ; | |
| int k = 2; | |
| return; | |
| } | |
| // CHECK: [B4 (ENTRY)] | |
| // CHECK-NEXT: Succs (1): B3 | |
| // CHECK: [B1] | |
| // CHECK-NEXT: 1: WhileStmt (LoopExit) | |
| // CHECK-NEXT: Preds (1): B3 | |
| // CHECK-NEXT: Succs (1): B0 | |
| // CHECK: [B2] | |
| // CHECK-NEXT: Succs (1): B3 | |
| // CHECK: [B3] | |
| // CHECK-NEXT: 1: false | |
| // CHECK-NEXT: T: while [B3.1] | |
| // CHECK-NEXT: Preds (2): B2 B4 | |
| // CHECK-NEXT: Succs (2): NULL B1 | |
| // CHECK: [B0 (EXIT)] | |
| // CHECK-NEXT: Preds (1): B1 | |
| void check_while3() { | |
| while (false) { | |
| ; | |
| } | |
| } | |
| // CHECK: [B4 (ENTRY)] | |
| // CHECK-NEXT: Succs (1): B2 | |
| // CHECK: [B1] | |
| // CHECK-NEXT: 1: DoStmt (LoopExit) | |
| // CHECK-NEXT: Preds (1): B2 | |
| // CHECK-NEXT: Succs (1): B0 | |
| // CHECK: [B2] | |
| // CHECK-NEXT: 1: false | |
| // CHECK-NEXT: T: do ... while [B2.1] | |
| // CHECK-NEXT: Preds (2): B3 B4 | |
| // CHECK-NEXT: Succs (2): NULL B1 | |
| // CHECK: [B3] | |
| // CHECK-NEXT: Succs (1): B2 | |
| // CHECK: [B0 (EXIT)] | |
| // CHECK-NEXT: Preds (1): B1 | |
| void check_dowhile1() { | |
| do { | |
| } while (false); | |
| } | |
| // CHECK: [B6 (ENTRY)] | |
| // CHECK-NEXT: Succs (1): B5 | |
| // CHECK: [B1] | |
| // CHECK-NEXT: 1: DoStmt (LoopExit) | |
| // CHECK-NEXT: 2: j | |
| // CHECK-NEXT: 3: [B1.2]-- | |
| // CHECK-NEXT: 4: return; | |
| // CHECK-NEXT: Preds (1): B2 | |
| // CHECK-NEXT: Succs (1): B0 | |
| // CHECK: [B2] | |
| // CHECK-NEXT: 1: j | |
| // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 3: 20 | |
| // CHECK-NEXT: 4: [B2.2] < [B2.3] | |
| // CHECK-NEXT: T: do ... while [B2.4] | |
| // CHECK-NEXT: Preds (1): B3 | |
| // CHECK-NEXT: Succs (2): B4 B1 | |
| // CHECK: [B3] | |
| // CHECK-NEXT: 1: j | |
| // CHECK-NEXT: 2: 2 | |
| // CHECK-NEXT: 3: [B3.1] += [B3.2] | |
| // CHECK-NEXT: Preds (2): B4 B5 | |
| // CHECK-NEXT: Succs (1): B2 | |
| // CHECK: [B4] | |
| // CHECK-NEXT: Preds (1): B2 | |
| // CHECK-NEXT: Succs (1): B3 | |
| // CHECK: [B5] | |
| // CHECK-NEXT: 1: 2 | |
| // CHECK-NEXT: 2: int j = 2; | |
| // CHECK-NEXT: Preds (1): B6 | |
| // CHECK-NEXT: Succs (1): B3 | |
| // CHECK: [B0 (EXIT)] | |
| // CHECK-NEXT: Preds (1): B1 | |
| void check_dowhile2() { | |
| int j = 2; | |
| do { | |
| j += 2; | |
| } while (j < 20); | |
| j--; | |
| return; | |
| } | |
| // CHECK: [B10 (ENTRY)] | |
| // CHECK-NEXT: Succs (1): B9 | |
| // CHECK: [B1] | |
| // CHECK-NEXT: 1: WhileStmt (LoopExit) | |
| // CHECK-NEXT: Preds (1): B8 | |
| // CHECK-NEXT: Succs (1): B0 | |
| // CHECK: [B2] | |
| // CHECK-NEXT: Preds (1): B3 | |
| // CHECK-NEXT: Succs (1): B8 | |
| // CHECK: [B3] | |
| // CHECK-NEXT: 1: ForStmt (LoopExit) | |
| // CHECK-NEXT: Preds (1): B6 | |
| // CHECK-NEXT: Succs (1): B2 | |
| // CHECK: [B4] | |
| // CHECK-NEXT: 1: j | |
| // CHECK-NEXT: 2: [B4.1]++ | |
| // CHECK-NEXT: Preds (1): B5 | |
| // CHECK-NEXT: Succs (1): B6 | |
| // CHECK: [B5] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B5.1]++ | |
| // CHECK-NEXT: Preds (1): B6 | |
| // CHECK-NEXT: Succs (1): B4 | |
| // CHECK: [B6] | |
| // CHECK-NEXT: 1: j | |
| // CHECK-NEXT: 2: [B6.1] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 3: 6 | |
| // CHECK-NEXT: 4: [B6.2] < [B6.3] | |
| // CHECK-NEXT: T: for (...; [B6.4]; ...) | |
| // CHECK-NEXT: Preds (2): B4 B7 | |
| // CHECK-NEXT: Succs (2): B5 B3 | |
| // CHECK: [B7] | |
| // CHECK-NEXT: 1: 1 | |
| // CHECK-NEXT: 2: int j = 1; | |
| // CHECK-NEXT: Preds (1): B8 | |
| // CHECK-NEXT: Succs (1): B6 | |
| // CHECK: [B8] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B8.1] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 3: 2 | |
| // CHECK-NEXT: 4: [B8.2] < [B8.3] | |
| // CHECK-NEXT: T: while [B8.4] | |
| // CHECK-NEXT: Preds (2): B2 B9 | |
| // CHECK-NEXT: Succs (2): B7 B1 | |
| // CHECK: [B9] | |
| // CHECK-NEXT: 1: 40 | |
| // CHECK-NEXT: 2: -[B9.1] | |
| // CHECK-NEXT: 3: int i = -40; | |
| // CHECK-NEXT: Preds (1): B10 | |
| // CHECK-NEXT: Succs (1): B8 | |
| // CHECK: [B0 (EXIT)] | |
| // CHECK-NEXT: Preds (1): B1 | |
| void nested_loops1() { | |
| int i = -40; | |
| while (i < 2) { | |
| for (int j = 1; j < 6; j++) | |
| i++; | |
| } | |
| } | |
| // CHECK: [B9 (ENTRY)] | |
| // CHECK-NEXT: Succs (1): B8 | |
| // CHECK: [B1] | |
| // CHECK-NEXT: 1: ForStmt (LoopExit) | |
| // CHECK-NEXT: Preds (1): B7 | |
| // CHECK-NEXT: Succs (1): B0 | |
| // CHECK: [B2] | |
| // CHECK-NEXT: 1: j | |
| // CHECK-NEXT: 2: [B2.1]++ | |
| // CHECK-NEXT: Preds (1): B3 | |
| // CHECK-NEXT: Succs (1): B7 | |
| // CHECK: [B3] | |
| // CHECK-NEXT: 1: DoStmt (LoopExit) | |
| // CHECK-NEXT: 2: i | |
| // CHECK-NEXT: 3: [B3.2]-- | |
| // CHECK-NEXT: Preds (1): B4 | |
| // CHECK-NEXT: Succs (1): B2 | |
| // CHECK: [B4] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 3: 2 | |
| // CHECK-NEXT: 4: [B4.2] < [B4.3] | |
| // CHECK-NEXT: T: do ... while [B4.4] | |
| // CHECK-NEXT: Preds (1): B5 | |
| // CHECK-NEXT: Succs (2): B6 B3 | |
| // CHECK: [B5] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B5.1]++ | |
| // CHECK-NEXT: Preds (2): B6 B7 | |
| // CHECK-NEXT: Succs (1): B4 | |
| // CHECK: [B6] | |
| // CHECK-NEXT: Preds (1): B4 | |
| // CHECK-NEXT: Succs (1): B5 | |
| // CHECK: [B7] | |
| // CHECK-NEXT: 1: j | |
| // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 3: 6 | |
| // CHECK-NEXT: 4: [B7.2] < [B7.3] | |
| // CHECK-NEXT: T: for (...; [B7.4]; ...) | |
| // CHECK-NEXT: Preds (2): B2 B8 | |
| // CHECK-NEXT: Succs (2): B5 B1 | |
| // CHECK: [B8] | |
| // CHECK-NEXT: 1: 40 | |
| // CHECK-NEXT: 2: -[B8.1] | |
| // CHECK-NEXT: 3: int i = -40; | |
| // CHECK-NEXT: 4: 1 | |
| // CHECK-NEXT: 5: int j = 1; | |
| // CHECK-NEXT: Preds (1): B9 | |
| // CHECK-NEXT: Succs (1): B7 | |
| // CHECK: [B0 (EXIT)] | |
| // CHECK-NEXT: Preds (1): B1 | |
| void nested_loops2() { | |
| int i = -40; | |
| for (int j = 1; j < 6; j++) { | |
| do { | |
| i++; | |
| } while (i < 2); | |
| i--; | |
| } | |
| } | |
| // CHECK: [B12 (ENTRY)] | |
| // CHECK-NEXT: Succs (1): B11 | |
| // CHECK: [B1] | |
| // CHECK-NEXT: 1: WhileStmt (LoopExit) | |
| // CHECK-NEXT: 2: return; | |
| // CHECK-NEXT: Preds (2): B3 B5 | |
| // CHECK-NEXT: Succs (1): B0 | |
| // CHECK: [B2] | |
| // CHECK-NEXT: Preds (1): B4 | |
| // CHECK-NEXT: Succs (1): B5 | |
| // CHECK: [B3] | |
| // CHECK-NEXT: T: break; | |
| // CHECK-NEXT: Preds (1): B4 | |
| // CHECK-NEXT: Succs (1): B1 | |
| // CHECK: [B4] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B4.1]++ | |
| // CHECK-NEXT: 3: i | |
| // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 5: 2 | |
| // CHECK-NEXT: 6: [B4.4] % [B4.5] | |
| // CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, IntegralToBoolean, _Bool) | |
| // CHECK-NEXT: T: if [B4.7] | |
| // CHECK-NEXT: Preds (1): B5 | |
| // CHECK-NEXT: Succs (2): B3 B2 | |
| // CHECK: [B5] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 3: 5 | |
| // CHECK-NEXT: 4: [B5.2] < [B5.3] | |
| // CHECK-NEXT: T: while [B5.4] | |
| // CHECK-NEXT: Preds (2): B2 B6 | |
| // CHECK-NEXT: Succs (2): B4 B1 | |
| // CHECK: [B6] | |
| // CHECK-NEXT: 1: ForStmt (LoopExit) | |
| // CHECK-NEXT: 2: 1 | |
| // CHECK-NEXT: 3: int i = 1; | |
| // CHECK-NEXT: Preds (2): B8 B10 | |
| // CHECK-NEXT: Succs (1): B5 | |
| // CHECK: [B7] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B7.1]++ | |
| // CHECK-NEXT: Preds (1): B9 | |
| // CHECK-NEXT: Succs (1): B10 | |
| // CHECK: [B8] | |
| // CHECK-NEXT: T: break; | |
| // CHECK-NEXT: Preds (1): B9 | |
| // CHECK-NEXT: Succs (1): B6 | |
| // CHECK: [B9] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B9.1] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 3: 4 | |
| // CHECK-NEXT: 4: [B9.2] == [B9.3] | |
| // CHECK-NEXT: T: if [B9.4] | |
| // CHECK-NEXT: Preds (1): B10 | |
| // CHECK-NEXT: Succs (2): B8 B7 | |
| // CHECK: [B10] | |
| // CHECK-NEXT: 1: i | |
| // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, LValueToRValue, int) | |
| // CHECK-NEXT: 3: 6 | |
| // CHECK-NEXT: 4: [B10.2] < [B10.3] | |
| // CHECK-NEXT: T: for (...; [B10.4]; ...) | |
| // CHECK-NEXT: Preds (2): B7 B11 | |
| // CHECK-NEXT: Succs (2): B9 B6 | |
| // CHECK: [B11] | |
| // CHECK-NEXT: 1: 2 | |
| // CHECK-NEXT: 2: int i = 2; | |
| // CHECK-NEXT: Preds (1): B12 | |
| // CHECK-NEXT: Succs (1): B10 | |
| // CHECK: [B0 (EXIT)] | |
| // CHECK-NEXT: Preds (1): B1 | |
| void check_break() | |
| { | |
| for(int i = 2; i < 6; i++) { | |
| if(i == 4) | |
| break; | |
| } | |
| int i = 1; | |
| while(i<5){ | |
| i++; | |
| if(i%2) | |
| break; | |
| } | |
| return; | |
| } |