1 // RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-loopexit=true %s > %t 2>&1 2 // RUN: FileCheck --input-file=%t %s 3 4 // CHECK: [B6 (ENTRY)] 5 // CHECK-NEXT: Succs (1): B5 6 7 // CHECK: [B1] 8 // CHECK-NEXT: 1: ForStmt (LoopExit) 9 // CHECK-NEXT: 2: return; 10 // CHECK-NEXT: Preds (1): B4 11 // CHECK-NEXT: Succs (1): B0 12 13 // CHECK: [B2] 14 // CHECK-NEXT: 1: i 15 // CHECK-NEXT: 2: [B2.1]++ 16 // CHECK-NEXT: Preds (1): B3 17 // CHECK-NEXT: Succs (1): B4 18 19 // CHECK: [B3] 20 // CHECK-NEXT: 1: i 21 // CHECK-NEXT: 2: [B3.1]++ 22 // CHECK-NEXT: Preds (1): B4 23 // CHECK-NEXT: Succs (1): B2 24 25 // CHECK: [B4] 26 // CHECK-NEXT: 1: i 27 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, int) 28 // CHECK-NEXT: 3: 12 29 // CHECK-NEXT: 4: [B4.2] < [B4.3] 30 // CHECK-NEXT: T: for (...; [B4.4]; ...) 31 // CHECK-NEXT: Preds (2): B2 B5 32 // CHECK-NEXT: Succs (2): B3 B1 33 34 // CHECK: [B5] 35 // CHECK-NEXT: 1: 0 36 // CHECK-NEXT: 2: int i = 0; 37 // CHECK-NEXT: Preds (1): B6 38 // CHECK-NEXT: Succs (1): B4 39 40 // CHECK: [B0 (EXIT)] 41 // CHECK-NEXT: Preds (1): B1 42 void check_forloop1() { 43 for (int i = 0; i < 12; i++) { 44 i++; 45 } 46 return; 47 } 48 49 // CHECK: [B4 (ENTRY)] 50 // CHECK-NEXT: Succs (1): B3 51 52 // CHECK: [B1] 53 // CHECK-NEXT: 1: ForStmt (LoopExit) 54 // CHECK-NEXT: Succs (1): B0 55 56 // CHECK: [B2] 57 // CHECK-NEXT: Preds (1): B3 58 // CHECK-NEXT: Succs (1): B3 59 60 // CHECK: [B3] 61 // CHECK-NEXT: T: for (; ; ) 62 // CHECK-NEXT: Preds (2): B2 B4 63 // CHECK-NEXT: Succs (2): B2 NULL 64 65 // CHECK: [B0 (EXIT)] 66 // CHECK-NEXT: Preds (1): B1 67 void check_forloop2() { 68 for (;;) 69 ; 70 } 71 72 // CHECK: [B5 (ENTRY)] 73 // CHECK-NEXT: Succs (1): B4 74 75 // CHECK: [B1] 76 // CHECK-NEXT: 1: WhileStmt (LoopExit) 77 // CHECK-NEXT: Succs (1): B0 78 79 // CHECK: [B2] 80 // CHECK-NEXT: Preds (1): B3 81 // CHECK-NEXT: Succs (1): B4 82 83 // CHECK: [B3] 84 // CHECK-NEXT: 1: int i; 85 // CHECK-NEXT: Preds (1): B4 86 // CHECK-NEXT: Succs (1): B2 87 88 // CHECK: [B4] 89 // CHECK-NEXT: 1: true 90 // CHECK-NEXT: T: while [B4.1] 91 // CHECK-NEXT: Preds (2): B2 B5 92 // CHECK-NEXT: Succs (2): B3 NULL 93 94 // CHECK: [B0 (EXIT)] 95 // CHECK-NEXT: Preds (1): B1 96 void check_while1() { 97 while (true) { 98 int i; 99 } 100 } 101 102 // CHECK: [B5 (ENTRY)] 103 // CHECK-NEXT: Succs (1): B4 104 105 // CHECK: [B1] 106 // CHECK-NEXT: 1: WhileStmt (LoopExit) 107 // CHECK-NEXT: 2: 2 108 // CHECK-NEXT: 3: int k = 2; 109 // CHECK-NEXT: 4: return; 110 // CHECK-NEXT: Preds (1): B3 111 // CHECK-NEXT: Succs (1): B0 112 113 // CHECK: [B2] 114 // CHECK-NEXT: Preds (1): B3 115 // CHECK-NEXT: Succs (1): B3 116 117 // CHECK: [B3] 118 // CHECK-NEXT: 1: l 119 // CHECK-NEXT: 2: [B3.1] (ImplicitCastExpr, LValueToRValue, int) 120 // CHECK-NEXT: 3: 42 121 // CHECK-NEXT: 4: [B3.2] < [B3.3] 122 // CHECK-NEXT: T: while [B3.4] 123 // CHECK-NEXT: Preds (2): B2 B4 124 // CHECK-NEXT: Succs (2): B2 B1 125 126 // CHECK: [B4] 127 // CHECK-NEXT: 1: int l; 128 // CHECK-NEXT: Preds (1): B5 129 // CHECK-NEXT: Succs (1): B3 130 131 // CHECK: [B0 (EXIT)] 132 // CHECK-NEXT: Preds (1): B1 133 void check_while2() { 134 int l; 135 while (l < 42) 136 ; 137 int k = 2; 138 return; 139 } 140 141 // CHECK: [B4 (ENTRY)] 142 // CHECK-NEXT: Succs (1): B3 143 144 // CHECK: [B1] 145 // CHECK-NEXT: 1: WhileStmt (LoopExit) 146 // CHECK-NEXT: Preds (1): B3 147 // CHECK-NEXT: Succs (1): B0 148 149 // CHECK: [B2] 150 // CHECK-NEXT: Succs (1): B3 151 152 // CHECK: [B3] 153 // CHECK-NEXT: 1: false 154 // CHECK-NEXT: T: while [B3.1] 155 // CHECK-NEXT: Preds (2): B2 B4 156 // CHECK-NEXT: Succs (2): NULL B1 157 158 // CHECK: [B0 (EXIT)] 159 // CHECK-NEXT: Preds (1): B1 160 void check_while3() { 161 while (false) { 162 ; 163 } 164 } 165 166 // CHECK: [B4 (ENTRY)] 167 // CHECK-NEXT: Succs (1): B2 168 169 // CHECK: [B1] 170 // CHECK-NEXT: 1: DoStmt (LoopExit) 171 // CHECK-NEXT: Preds (1): B2 172 // CHECK-NEXT: Succs (1): B0 173 174 // CHECK: [B2] 175 // CHECK-NEXT: 1: false 176 // CHECK-NEXT: T: do ... while [B2.1] 177 // CHECK-NEXT: Preds (2): B3 B4 178 // CHECK-NEXT: Succs (2): NULL B1 179 180 // CHECK: [B3] 181 // CHECK-NEXT: Succs (1): B2 182 183 // CHECK: [B0 (EXIT)] 184 // CHECK-NEXT: Preds (1): B1 185 void check_dowhile1() { 186 do { 187 } while (false); 188 } 189 190 // CHECK: [B6 (ENTRY)] 191 // CHECK-NEXT: Succs (1): B5 192 193 // CHECK: [B1] 194 // CHECK-NEXT: 1: DoStmt (LoopExit) 195 // CHECK-NEXT: 2: j 196 // CHECK-NEXT: 3: [B1.2]-- 197 // CHECK-NEXT: 4: return; 198 // CHECK-NEXT: Preds (1): B2 199 // CHECK-NEXT: Succs (1): B0 200 201 // CHECK: [B2] 202 // CHECK-NEXT: 1: j 203 // CHECK-NEXT: 2: [B2.1] (ImplicitCastExpr, LValueToRValue, int) 204 // CHECK-NEXT: 3: 20 205 // CHECK-NEXT: 4: [B2.2] < [B2.3] 206 // CHECK-NEXT: T: do ... while [B2.4] 207 // CHECK-NEXT: Preds (1): B3 208 // CHECK-NEXT: Succs (2): B4 B1 209 210 // CHECK: [B3] 211 // CHECK-NEXT: 1: j 212 // CHECK-NEXT: 2: 2 213 // CHECK-NEXT: 3: [B3.1] += [B3.2] 214 // CHECK-NEXT: Preds (2): B4 B5 215 // CHECK-NEXT: Succs (1): B2 216 217 // CHECK: [B4] 218 // CHECK-NEXT: Preds (1): B2 219 // CHECK-NEXT: Succs (1): B3 220 221 // CHECK: [B5] 222 // CHECK-NEXT: 1: 2 223 // CHECK-NEXT: 2: int j = 2; 224 // CHECK-NEXT: Preds (1): B6 225 // CHECK-NEXT: Succs (1): B3 226 227 // CHECK: [B0 (EXIT)] 228 // CHECK-NEXT: Preds (1): B1 229 void check_dowhile2() { 230 int j = 2; 231 do { 232 j += 2; 233 } while (j < 20); 234 j--; 235 return; 236 } 237 238 // CHECK: [B10 (ENTRY)] 239 // CHECK-NEXT: Succs (1): B9 240 241 // CHECK: [B1] 242 // CHECK-NEXT: 1: WhileStmt (LoopExit) 243 // CHECK-NEXT: Preds (1): B8 244 // CHECK-NEXT: Succs (1): B0 245 246 // CHECK: [B2] 247 // CHECK-NEXT: Preds (1): B3 248 // CHECK-NEXT: Succs (1): B8 249 250 // CHECK: [B3] 251 // CHECK-NEXT: 1: ForStmt (LoopExit) 252 // CHECK-NEXT: Preds (1): B6 253 // CHECK-NEXT: Succs (1): B2 254 255 // CHECK: [B4] 256 // CHECK-NEXT: 1: j 257 // CHECK-NEXT: 2: [B4.1]++ 258 // CHECK-NEXT: Preds (1): B5 259 // CHECK-NEXT: Succs (1): B6 260 261 // CHECK: [B5] 262 // CHECK-NEXT: 1: i 263 // CHECK-NEXT: 2: [B5.1]++ 264 // CHECK-NEXT: Preds (1): B6 265 // CHECK-NEXT: Succs (1): B4 266 267 // CHECK: [B6] 268 // CHECK-NEXT: 1: j 269 // CHECK-NEXT: 2: [B6.1] (ImplicitCastExpr, LValueToRValue, int) 270 // CHECK-NEXT: 3: 6 271 // CHECK-NEXT: 4: [B6.2] < [B6.3] 272 // CHECK-NEXT: T: for (...; [B6.4]; ...) 273 // CHECK-NEXT: Preds (2): B4 B7 274 // CHECK-NEXT: Succs (2): B5 B3 275 276 // CHECK: [B7] 277 // CHECK-NEXT: 1: 1 278 // CHECK-NEXT: 2: int j = 1; 279 // CHECK-NEXT: Preds (1): B8 280 // CHECK-NEXT: Succs (1): B6 281 282 // CHECK: [B8] 283 // CHECK-NEXT: 1: i 284 // CHECK-NEXT: 2: [B8.1] (ImplicitCastExpr, LValueToRValue, int) 285 // CHECK-NEXT: 3: 2 286 // CHECK-NEXT: 4: [B8.2] < [B8.3] 287 // CHECK-NEXT: T: while [B8.4] 288 // CHECK-NEXT: Preds (2): B2 B9 289 // CHECK-NEXT: Succs (2): B7 B1 290 291 // CHECK: [B9] 292 // CHECK-NEXT: 1: 40 293 // CHECK-NEXT: 2: -[B9.1] 294 // CHECK-NEXT: 3: int i = -40; 295 // CHECK-NEXT: Preds (1): B10 296 // CHECK-NEXT: Succs (1): B8 297 298 // CHECK: [B0 (EXIT)] 299 // CHECK-NEXT: Preds (1): B1 300 void nested_loops1() { 301 int i = -40; 302 while (i < 2) { 303 for (int j = 1; j < 6; j++) 304 i++; 305 } 306 } 307 308 // CHECK: [B9 (ENTRY)] 309 // CHECK-NEXT: Succs (1): B8 310 311 // CHECK: [B1] 312 // CHECK-NEXT: 1: ForStmt (LoopExit) 313 // CHECK-NEXT: Preds (1): B7 314 // CHECK-NEXT: Succs (1): B0 315 316 // CHECK: [B2] 317 // CHECK-NEXT: 1: j 318 // CHECK-NEXT: 2: [B2.1]++ 319 // CHECK-NEXT: Preds (1): B3 320 // CHECK-NEXT: Succs (1): B7 321 322 // CHECK: [B3] 323 // CHECK-NEXT: 1: DoStmt (LoopExit) 324 // CHECK-NEXT: 2: i 325 // CHECK-NEXT: 3: [B3.2]-- 326 // CHECK-NEXT: Preds (1): B4 327 // CHECK-NEXT: Succs (1): B2 328 329 // CHECK: [B4] 330 // CHECK-NEXT: 1: i 331 // CHECK-NEXT: 2: [B4.1] (ImplicitCastExpr, LValueToRValue, int) 332 // CHECK-NEXT: 3: 2 333 // CHECK-NEXT: 4: [B4.2] < [B4.3] 334 // CHECK-NEXT: T: do ... while [B4.4] 335 // CHECK-NEXT: Preds (1): B5 336 // CHECK-NEXT: Succs (2): B6 B3 337 338 // CHECK: [B5] 339 // CHECK-NEXT: 1: i 340 // CHECK-NEXT: 2: [B5.1]++ 341 // CHECK-NEXT: Preds (2): B6 B7 342 // CHECK-NEXT: Succs (1): B4 343 344 // CHECK: [B6] 345 // CHECK-NEXT: Preds (1): B4 346 // CHECK-NEXT: Succs (1): B5 347 348 // CHECK: [B7] 349 // CHECK-NEXT: 1: j 350 // CHECK-NEXT: 2: [B7.1] (ImplicitCastExpr, LValueToRValue, int) 351 // CHECK-NEXT: 3: 6 352 // CHECK-NEXT: 4: [B7.2] < [B7.3] 353 // CHECK-NEXT: T: for (...; [B7.4]; ...) 354 // CHECK-NEXT: Preds (2): B2 B8 355 // CHECK-NEXT: Succs (2): B5 B1 356 357 // CHECK: [B8] 358 // CHECK-NEXT: 1: 40 359 // CHECK-NEXT: 2: -[B8.1] 360 // CHECK-NEXT: 3: int i = -40; 361 // CHECK-NEXT: 4: 1 362 // CHECK-NEXT: 5: int j = 1; 363 // CHECK-NEXT: Preds (1): B9 364 // CHECK-NEXT: Succs (1): B7 365 366 // CHECK: [B0 (EXIT)] 367 // CHECK-NEXT: Preds (1): B1 368 void nested_loops2() { 369 int i = -40; 370 for (int j = 1; j < 6; j++) { 371 do { 372 i++; 373 } while (i < 2); 374 i--; 375 } 376 } 377 378 // CHECK: [B12 (ENTRY)] 379 // CHECK-NEXT: Succs (1): B11 380 381 // CHECK: [B1] 382 // CHECK-NEXT: 1: WhileStmt (LoopExit) 383 // CHECK-NEXT: 2: return; 384 // CHECK-NEXT: Preds (2): B3 B5 385 // CHECK-NEXT: Succs (1): B0 386 387 // CHECK: [B2] 388 // CHECK-NEXT: Preds (1): B4 389 // CHECK-NEXT: Succs (1): B5 390 391 // CHECK: [B3] 392 // CHECK-NEXT: T: break; 393 // CHECK-NEXT: Preds (1): B4 394 // CHECK-NEXT: Succs (1): B1 395 396 // CHECK: [B4] 397 // CHECK-NEXT: 1: i 398 // CHECK-NEXT: 2: [B4.1]++ 399 // CHECK-NEXT: 3: i 400 // CHECK-NEXT: 4: [B4.3] (ImplicitCastExpr, LValueToRValue, int) 401 // CHECK-NEXT: 5: 2 402 // CHECK-NEXT: 6: [B4.4] % [B4.5] 403 // CHECK-NEXT: 7: [B4.6] (ImplicitCastExpr, IntegralToBoolean, _Bool) 404 // CHECK-NEXT: T: if [B4.7] 405 // CHECK-NEXT: Preds (1): B5 406 // CHECK-NEXT: Succs (2): B3 B2 407 408 // CHECK: [B5] 409 // CHECK-NEXT: 1: i 410 // CHECK-NEXT: 2: [B5.1] (ImplicitCastExpr, LValueToRValue, int) 411 // CHECK-NEXT: 3: 5 412 // CHECK-NEXT: 4: [B5.2] < [B5.3] 413 // CHECK-NEXT: T: while [B5.4] 414 // CHECK-NEXT: Preds (2): B2 B6 415 // CHECK-NEXT: Succs (2): B4 B1 416 417 // CHECK: [B6] 418 // CHECK-NEXT: 1: ForStmt (LoopExit) 419 // CHECK-NEXT: 2: 1 420 // CHECK-NEXT: 3: int i = 1; 421 // CHECK-NEXT: Preds (2): B8 B10 422 // CHECK-NEXT: Succs (1): B5 423 424 // CHECK: [B7] 425 // CHECK-NEXT: 1: i 426 // CHECK-NEXT: 2: [B7.1]++ 427 // CHECK-NEXT: Preds (1): B9 428 // CHECK-NEXT: Succs (1): B10 429 430 // CHECK: [B8] 431 // CHECK-NEXT: T: break; 432 // CHECK-NEXT: Preds (1): B9 433 // CHECK-NEXT: Succs (1): B6 434 435 // CHECK: [B9] 436 // CHECK-NEXT: 1: i 437 // CHECK-NEXT: 2: [B9.1] (ImplicitCastExpr, LValueToRValue, int) 438 // CHECK-NEXT: 3: 4 439 // CHECK-NEXT: 4: [B9.2] == [B9.3] 440 // CHECK-NEXT: T: if [B9.4] 441 // CHECK-NEXT: Preds (1): B10 442 // CHECK-NEXT: Succs (2): B8 B7 443 444 // CHECK: [B10] 445 // CHECK-NEXT: 1: i 446 // CHECK-NEXT: 2: [B10.1] (ImplicitCastExpr, LValueToRValue, int) 447 // CHECK-NEXT: 3: 6 448 // CHECK-NEXT: 4: [B10.2] < [B10.3] 449 // CHECK-NEXT: T: for (...; [B10.4]; ...) 450 // CHECK-NEXT: Preds (2): B7 B11 451 // CHECK-NEXT: Succs (2): B9 B6 452 453 // CHECK: [B11] 454 // CHECK-NEXT: 1: 2 455 // CHECK-NEXT: 2: int i = 2; 456 // CHECK-NEXT: Preds (1): B12 457 // CHECK-NEXT: Succs (1): B10 458 459 // CHECK: [B0 (EXIT)] 460 // CHECK-NEXT: Preds (1): B1 461 void check_break() 462 { 463 for(int i = 2; i < 6; i++) { 464 if(i == 4) 465 break; 466 } 467 468 int i = 1; 469 while(i<5){ 470 i++; 471 if(i%2) 472 break; 473 } 474 475 return; 476 } 477