[FIR] Do not terminate smartcast CFG nodes when result is Nothing

Terminating a CFG node because the result is Nothing should be reserved
for explicit Nothing type definitions, and not apply when smartcasting.
This allows boolean expressions to propagate implications correctly even
when the RHS is impossible or will never be executed.

^KT-47931 Fixed
This commit is contained in:
Brian Norman
2023-11-14 10:21:38 -06:00
committed by Space Team
parent e92fab65aa
commit a4b3b08e59
6 changed files with 298 additions and 309 deletions
@@ -740,47 +740,46 @@ digraph boundSmartcastsInBranches_kt {
313 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"]; 313 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
314 [label="Access variable R|<local>/y|"]; 314 [label="Access variable R|<local>/y|"];
315 [label="Smart cast: R|<local>/y|"]; 315 [label="Smart cast: R|<local>/y|"];
316 [label="Stub" style="filled" fillcolor=gray]; 316 [label="Access variable R|kotlin/String.length|"];
317 [label="Access variable R|kotlin/String.length|" style="filled" fillcolor=gray]; 317 [label="Access variable R|<local>/z|"];
318 [label="Access variable R|<local>/z|" style="filled" fillcolor=gray]; 318 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
319 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|" style="filled" fillcolor=gray]; 319 [label="Exit block"];
320 [label="Exit block" style="filled" fillcolor=gray];
} }
321 [label="Exit when branch result" style="filled" fillcolor=gray]; 320 [label="Exit when branch result"];
322 [label="Exit when"]; 321 [label="Exit when"];
} }
subgraph cluster_69 { subgraph cluster_69 {
color=blue color=blue
323 [label="Enter when"]; 322 [label="Enter when"];
subgraph cluster_70 { subgraph cluster_70 {
color=blue color=blue
324 [label="Enter when branch condition "]; 323 [label="Enter when branch condition "];
325 [label="Access variable R|<local>/z|"]; 324 [label="Access variable R|<local>/z|"];
326 [label="Const: Null(null)"]; 325 [label="Const: Null(null)"];
327 [label="Equality operator !="]; 326 [label="Equality operator !="];
328 [label="Exit when branch condition"]; 327 [label="Exit when branch condition"];
} }
329 [label="Synthetic else branch"]; 328 [label="Synthetic else branch"];
330 [label="Enter when branch result"]; 329 [label="Enter when branch result"];
subgraph cluster_71 { subgraph cluster_71 {
color=blue color=blue
331 [label="Enter block"]; 330 [label="Enter block"];
332 [label="Access variable R|<local>/x|"]; 331 [label="Access variable R|<local>/x|"];
333 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"]; 332 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
334 [label="Access variable R|<local>/y|"]; 333 [label="Access variable R|<local>/y|"];
335 [label="Smart cast: R|<local>/y|"]; 334 [label="Smart cast: R|<local>/y|"];
336 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"]; 335 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
337 [label="Access variable R|<local>/z|"]; 336 [label="Access variable R|<local>/z|"];
338 [label="Smart cast: R|<local>/z|"]; 337 [label="Smart cast: R|<local>/z|"];
339 [label="Access variable R|kotlin/String.length|"]; 338 [label="Access variable R|kotlin/String.length|"];
340 [label="Exit block"]; 339 [label="Exit block"];
} }
341 [label="Exit when branch result"]; 340 [label="Exit when branch result"];
342 [label="Exit when"]; 341 [label="Exit when"];
} }
343 [label="Exit block"]; 342 [label="Exit block"];
} }
344 [label="Exit function test_7" style="filled" fillcolor=red]; 343 [label="Exit function test_7" style="filled" fillcolor=red];
} }
215 -> {216}; 215 -> {216};
216 -> {217}; 216 -> {217};
@@ -876,27 +875,27 @@ digraph boundSmartcastsInBranches_kt {
306 -> {307}; 306 -> {307};
307 -> {308}; 307 -> {308};
308 -> {309 310}; 308 -> {309 310};
309 -> {322}; 309 -> {321};
310 -> {311}; 310 -> {311};
311 -> {312}; 311 -> {312};
312 -> {313}; 312 -> {313};
313 -> {314}; 313 -> {314};
314 -> {315}; 314 -> {315};
315 -> {316} [style=dotted]; 315 -> {316};
316 -> {317} [style=dotted]; 316 -> {317};
317 -> {318} [style=dotted]; 317 -> {318};
318 -> {319} [style=dotted]; 318 -> {319};
319 -> {320} [style=dotted]; 319 -> {320};
320 -> {321} [style=dotted]; 320 -> {321};
321 -> {322} [style=dotted]; 321 -> {322};
322 -> {323}; 322 -> {323};
323 -> {324}; 323 -> {324};
324 -> {325}; 324 -> {325};
325 -> {326}; 325 -> {326};
326 -> {327}; 326 -> {327};
327 -> {328}; 327 -> {328 329};
328 -> {329 330}; 328 -> {341};
329 -> {342}; 329 -> {330};
330 -> {331}; 330 -> {331};
331 -> {332}; 331 -> {332};
332 -> {333}; 332 -> {333};
@@ -910,206 +909,205 @@ digraph boundSmartcastsInBranches_kt {
340 -> {341}; 340 -> {341};
341 -> {342}; 341 -> {342};
342 -> {343}; 342 -> {343};
343 -> {344};
subgraph cluster_72 { subgraph cluster_72 {
color=red color=red
345 [label="Enter function test_8" style="filled" fillcolor=red]; 344 [label="Enter function test_8" style="filled" fillcolor=red];
subgraph cluster_73 { subgraph cluster_73 {
color=blue color=blue
346 [label="Enter block"]; 345 [label="Enter block"];
347 [label="Const: Null(null)"]; 346 [label="Const: Null(null)"];
348 [label="Variable declaration: lval z: R|kotlin/String?|"]; 347 [label="Variable declaration: lval z: R|kotlin/String?|"];
349 [label="Access variable R|<local>/z|"]; 348 [label="Access variable R|<local>/z|"];
350 [label="Variable declaration: lvar y: R|kotlin/String?|"]; 349 [label="Variable declaration: lvar y: R|kotlin/String?|"];
351 [label="Access variable R|<local>/y|"]; 350 [label="Access variable R|<local>/y|"];
352 [label="Variable declaration: lval x: R|kotlin/String?|"]; 351 [label="Variable declaration: lval x: R|kotlin/String?|"];
subgraph cluster_74 { subgraph cluster_74 {
color=blue color=blue
353 [label="Enter when"]; 352 [label="Enter when"];
subgraph cluster_75 { subgraph cluster_75 {
color=blue color=blue
354 [label="Enter when branch condition "]; 353 [label="Enter when branch condition "];
355 [label="Access variable R|<local>/x|"]; 354 [label="Access variable R|<local>/x|"];
356 [label="Const: Null(null)"]; 355 [label="Const: Null(null)"];
357 [label="Equality operator !="]; 356 [label="Equality operator !="];
358 [label="Exit when branch condition"]; 357 [label="Exit when branch condition"];
} }
359 [label="Synthetic else branch"]; 358 [label="Synthetic else branch"];
360 [label="Enter when branch result"]; 359 [label="Enter when branch result"];
subgraph cluster_76 { subgraph cluster_76 {
color=blue color=blue
361 [label="Enter block"]; 360 [label="Enter block"];
362 [label="Access variable R|<local>/x|"]; 361 [label="Access variable R|<local>/x|"];
363 [label="Smart cast: R|<local>/x|"]; 362 [label="Smart cast: R|<local>/x|"];
364 [label="Access variable R|kotlin/String.length|"]; 363 [label="Access variable R|kotlin/String.length|"];
365 [label="Access variable R|<local>/y|"]; 364 [label="Access variable R|<local>/y|"];
366 [label="Smart cast: R|<local>/y|"]; 365 [label="Smart cast: R|<local>/y|"];
367 [label="Access variable R|kotlin/String.length|"]; 366 [label="Access variable R|kotlin/String.length|"];
368 [label="Access variable R|<local>/z|"]; 367 [label="Access variable R|<local>/z|"];
369 [label="Smart cast: R|<local>/z|"]; 368 [label="Smart cast: R|<local>/z|"];
370 [label="Access variable R|kotlin/String.length|"]; 369 [label="Access variable R|kotlin/String.length|"];
371 [label="Exit block"]; 370 [label="Exit block"];
} }
372 [label="Exit when branch result"]; 371 [label="Exit when branch result"];
373 [label="Exit when"]; 372 [label="Exit when"];
} }
subgraph cluster_77 { subgraph cluster_77 {
color=blue color=blue
374 [label="Enter when"]; 373 [label="Enter when"];
subgraph cluster_78 { subgraph cluster_78 {
color=blue color=blue
375 [label="Enter when branch condition "]; 374 [label="Enter when branch condition "];
376 [label="Access variable R|<local>/y|"]; 375 [label="Access variable R|<local>/y|"];
377 [label="Const: Null(null)"]; 376 [label="Const: Null(null)"];
378 [label="Equality operator !="]; 377 [label="Equality operator !="];
379 [label="Exit when branch condition"]; 378 [label="Exit when branch condition"];
} }
380 [label="Synthetic else branch"]; 379 [label="Synthetic else branch"];
381 [label="Enter when branch result"]; 380 [label="Enter when branch result"];
subgraph cluster_79 { subgraph cluster_79 {
color=blue color=blue
382 [label="Enter block"]; 381 [label="Enter block"];
383 [label="Access variable R|<local>/x|"]; 382 [label="Access variable R|<local>/x|"];
384 [label="Smart cast: R|<local>/x|"]; 383 [label="Smart cast: R|<local>/x|"];
385 [label="Access variable R|kotlin/String.length|"]; 384 [label="Access variable R|kotlin/String.length|"];
386 [label="Access variable R|<local>/y|"]; 385 [label="Access variable R|<local>/y|"];
387 [label="Smart cast: R|<local>/y|"]; 386 [label="Smart cast: R|<local>/y|"];
388 [label="Access variable R|kotlin/String.length|"]; 387 [label="Access variable R|kotlin/String.length|"];
389 [label="Access variable R|<local>/z|"]; 388 [label="Access variable R|<local>/z|"];
390 [label="Smart cast: R|<local>/z|"]; 389 [label="Smart cast: R|<local>/z|"];
391 [label="Access variable R|kotlin/String.length|"]; 390 [label="Access variable R|kotlin/String.length|"];
392 [label="Exit block"]; 391 [label="Exit block"];
} }
393 [label="Exit when branch result"]; 392 [label="Exit when branch result"];
394 [label="Exit when"]; 393 [label="Exit when"];
} }
subgraph cluster_80 { subgraph cluster_80 {
color=blue color=blue
395 [label="Enter when"]; 394 [label="Enter when"];
subgraph cluster_81 { subgraph cluster_81 {
color=blue color=blue
396 [label="Enter when branch condition "]; 395 [label="Enter when branch condition "];
397 [label="Access variable R|<local>/z|"]; 396 [label="Access variable R|<local>/z|"];
398 [label="Const: Null(null)"]; 397 [label="Const: Null(null)"];
399 [label="Equality operator !="]; 398 [label="Equality operator !="];
400 [label="Exit when branch condition"]; 399 [label="Exit when branch condition"];
} }
401 [label="Synthetic else branch"]; 400 [label="Synthetic else branch"];
402 [label="Enter when branch result"]; 401 [label="Enter when branch result"];
subgraph cluster_82 { subgraph cluster_82 {
color=blue color=blue
403 [label="Enter block"]; 402 [label="Enter block"];
404 [label="Access variable R|<local>/x|"]; 403 [label="Access variable R|<local>/x|"];
405 [label="Smart cast: R|<local>/x|"]; 404 [label="Smart cast: R|<local>/x|"];
406 [label="Access variable R|kotlin/String.length|"]; 405 [label="Access variable R|kotlin/String.length|"];
407 [label="Access variable R|<local>/y|"]; 406 [label="Access variable R|<local>/y|"];
408 [label="Smart cast: R|<local>/y|"]; 407 [label="Smart cast: R|<local>/y|"];
409 [label="Access variable R|kotlin/String.length|"]; 408 [label="Access variable R|kotlin/String.length|"];
410 [label="Access variable R|<local>/z|"]; 409 [label="Access variable R|<local>/z|"];
411 [label="Smart cast: R|<local>/z|"]; 410 [label="Smart cast: R|<local>/z|"];
412 [label="Access variable R|kotlin/String.length|"]; 411 [label="Access variable R|kotlin/String.length|"];
413 [label="Exit block"]; 412 [label="Exit block"];
} }
414 [label="Exit when branch result"]; 413 [label="Exit when branch result"];
415 [label="Exit when"]; 414 [label="Exit when"];
} }
416 [label="Const: Null(null)"]; 415 [label="Const: Null(null)"];
417 [label="Assignment: R|<local>/y|"]; 416 [label="Assignment: R|<local>/y|"];
subgraph cluster_83 { subgraph cluster_83 {
color=blue color=blue
418 [label="Enter when"]; 417 [label="Enter when"];
subgraph cluster_84 { subgraph cluster_84 {
color=blue color=blue
419 [label="Enter when branch condition "]; 418 [label="Enter when branch condition "];
420 [label="Access variable R|<local>/x|"]; 419 [label="Access variable R|<local>/x|"];
421 [label="Const: Null(null)"]; 420 [label="Const: Null(null)"];
422 [label="Equality operator !="]; 421 [label="Equality operator !="];
423 [label="Exit when branch condition"]; 422 [label="Exit when branch condition"];
} }
424 [label="Synthetic else branch"]; 423 [label="Synthetic else branch"];
425 [label="Enter when branch result"]; 424 [label="Enter when branch result"];
subgraph cluster_85 { subgraph cluster_85 {
color=blue color=blue
426 [label="Enter block"]; 425 [label="Enter block"];
427 [label="Access variable R|<local>/x|"]; 426 [label="Access variable R|<local>/x|"];
428 [label="Smart cast: R|<local>/x|"]; 427 [label="Smart cast: R|<local>/x|"];
429 [label="Access variable R|kotlin/String.length|"]; 428 [label="Access variable R|kotlin/String.length|"];
430 [label="Access variable R|<local>/y|"]; 429 [label="Access variable R|<local>/y|"];
431 [label="Smart cast: R|<local>/y|"]; 430 [label="Smart cast: R|<local>/y|"];
432 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"]; 431 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
433 [label="Access variable R|<local>/z|"]; 432 [label="Access variable R|<local>/z|"];
434 [label="Smart cast: R|<local>/z|"]; 433 [label="Smart cast: R|<local>/z|"];
435 [label="Access variable R|kotlin/String.length|"]; 434 [label="Access variable R|kotlin/String.length|"];
436 [label="Exit block"]; 435 [label="Exit block"];
} }
437 [label="Exit when branch result"]; 436 [label="Exit when branch result"];
438 [label="Exit when"]; 437 [label="Exit when"];
} }
subgraph cluster_86 { subgraph cluster_86 {
color=blue color=blue
439 [label="Enter when"]; 438 [label="Enter when"];
subgraph cluster_87 { subgraph cluster_87 {
color=blue color=blue
440 [label="Enter when branch condition "]; 439 [label="Enter when branch condition "];
441 [label="Access variable R|<local>/y|"]; 440 [label="Access variable R|<local>/y|"];
442 [label="Smart cast: R|<local>/y|"]; 441 [label="Smart cast: R|<local>/y|"];
443 [label="Const: Null(null)"]; 442 [label="Const: Null(null)"];
444 [label="Equality operator !="]; 443 [label="Equality operator !="];
445 [label="Exit when branch condition"]; 444 [label="Exit when branch condition"];
} }
446 [label="Synthetic else branch"]; 445 [label="Synthetic else branch"];
447 [label="Enter when branch result"]; 446 [label="Enter when branch result"];
subgraph cluster_88 { subgraph cluster_88 {
color=blue color=blue
448 [label="Enter block"]; 447 [label="Enter block"];
449 [label="Access variable R|<local>/x|"]; 448 [label="Access variable R|<local>/x|"];
450 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"]; 449 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
451 [label="Access variable R|<local>/y|"]; 450 [label="Access variable R|<local>/y|"];
452 [label="Smart cast: R|<local>/y|"]; 451 [label="Smart cast: R|<local>/y|"];
453 [label="Stub" style="filled" fillcolor=gray]; 452 [label="Access variable R|kotlin/String.length|"];
454 [label="Access variable R|kotlin/String.length|" style="filled" fillcolor=gray]; 453 [label="Access variable R|<local>/z|"];
455 [label="Access variable R|<local>/z|" style="filled" fillcolor=gray]; 454 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
456 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|" style="filled" fillcolor=gray]; 455 [label="Exit block"];
457 [label="Exit block" style="filled" fillcolor=gray];
} }
458 [label="Exit when branch result" style="filled" fillcolor=gray]; 456 [label="Exit when branch result"];
459 [label="Exit when"]; 457 [label="Exit when"];
} }
subgraph cluster_89 { subgraph cluster_89 {
color=blue color=blue
460 [label="Enter when"]; 458 [label="Enter when"];
subgraph cluster_90 { subgraph cluster_90 {
color=blue color=blue
461 [label="Enter when branch condition "]; 459 [label="Enter when branch condition "];
462 [label="Access variable R|<local>/z|"]; 460 [label="Access variable R|<local>/z|"];
463 [label="Const: Null(null)"]; 461 [label="Const: Null(null)"];
464 [label="Equality operator !="]; 462 [label="Equality operator !="];
465 [label="Exit when branch condition"]; 463 [label="Exit when branch condition"];
} }
466 [label="Synthetic else branch"]; 464 [label="Synthetic else branch"];
467 [label="Enter when branch result"]; 465 [label="Enter when branch result"];
subgraph cluster_91 { subgraph cluster_91 {
color=blue color=blue
468 [label="Enter block"]; 466 [label="Enter block"];
469 [label="Access variable R|<local>/x|"]; 467 [label="Access variable R|<local>/x|"];
470 [label="Smart cast: R|<local>/x|"]; 468 [label="Smart cast: R|<local>/x|"];
471 [label="Access variable R|kotlin/String.length|"]; 469 [label="Access variable R|kotlin/String.length|"];
472 [label="Access variable R|<local>/y|"]; 470 [label="Access variable R|<local>/y|"];
473 [label="Smart cast: R|<local>/y|"]; 471 [label="Smart cast: R|<local>/y|"];
474 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"]; 472 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
475 [label="Access variable R|<local>/z|"]; 473 [label="Access variable R|<local>/z|"];
476 [label="Smart cast: R|<local>/z|"]; 474 [label="Smart cast: R|<local>/z|"];
477 [label="Access variable R|kotlin/String.length|"]; 475 [label="Access variable R|kotlin/String.length|"];
478 [label="Exit block"]; 476 [label="Exit block"];
} }
479 [label="Exit when branch result"]; 477 [label="Exit when branch result"];
480 [label="Exit when"]; 478 [label="Exit when"];
} }
481 [label="Exit block"]; 479 [label="Exit block"];
} }
482 [label="Exit function test_8" style="filled" fillcolor=red]; 480 [label="Exit function test_8" style="filled" fillcolor=red];
} }
344 -> {345};
345 -> {346}; 345 -> {346};
346 -> {347}; 346 -> {347};
347 -> {348}; 347 -> {348};
@@ -1122,9 +1120,9 @@ digraph boundSmartcastsInBranches_kt {
354 -> {355}; 354 -> {355};
355 -> {356}; 355 -> {356};
356 -> {357}; 356 -> {357};
357 -> {358}; 357 -> {358 359};
358 -> {359 360}; 358 -> {372};
359 -> {373}; 359 -> {360};
360 -> {361}; 360 -> {361};
361 -> {362}; 361 -> {362};
362 -> {363}; 362 -> {363};
@@ -1143,9 +1141,9 @@ digraph boundSmartcastsInBranches_kt {
375 -> {376}; 375 -> {376};
376 -> {377}; 376 -> {377};
377 -> {378}; 377 -> {378};
378 -> {379}; 378 -> {379 380};
379 -> {380 381}; 379 -> {393};
380 -> {394}; 380 -> {381};
381 -> {382}; 381 -> {382};
382 -> {383}; 382 -> {383};
383 -> {384}; 383 -> {384};
@@ -1164,9 +1162,9 @@ digraph boundSmartcastsInBranches_kt {
396 -> {397}; 396 -> {397};
397 -> {398}; 397 -> {398};
398 -> {399}; 398 -> {399};
399 -> {400}; 399 -> {400 401};
400 -> {401 402}; 400 -> {414};
401 -> {415}; 401 -> {402};
402 -> {403}; 402 -> {403};
403 -> {404}; 403 -> {404};
404 -> {405}; 404 -> {405};
@@ -1187,9 +1185,9 @@ digraph boundSmartcastsInBranches_kt {
419 -> {420}; 419 -> {420};
420 -> {421}; 420 -> {421};
421 -> {422}; 421 -> {422};
422 -> {423}; 422 -> {423 424};
423 -> {424 425}; 423 -> {437};
424 -> {438}; 424 -> {425};
425 -> {426}; 425 -> {426};
426 -> {427}; 426 -> {427};
427 -> {428}; 427 -> {428};
@@ -1209,29 +1207,29 @@ digraph boundSmartcastsInBranches_kt {
441 -> {442}; 441 -> {442};
442 -> {443}; 442 -> {443};
443 -> {444}; 443 -> {444};
444 -> {445}; 444 -> {445 446};
445 -> {446 447}; 445 -> {457};
446 -> {459}; 446 -> {447};
447 -> {448}; 447 -> {448};
448 -> {449}; 448 -> {449};
449 -> {450}; 449 -> {450};
450 -> {451}; 450 -> {451};
451 -> {452}; 451 -> {452};
452 -> {453} [style=dotted]; 452 -> {453};
453 -> {454} [style=dotted]; 453 -> {454};
454 -> {455} [style=dotted]; 454 -> {455};
455 -> {456} [style=dotted]; 455 -> {456};
456 -> {457} [style=dotted]; 456 -> {457};
457 -> {458} [style=dotted]; 457 -> {458};
458 -> {459} [style=dotted]; 458 -> {459};
459 -> {460}; 459 -> {460};
460 -> {461}; 460 -> {461};
461 -> {462}; 461 -> {462};
462 -> {463}; 462 -> {463};
463 -> {464}; 463 -> {464 465};
464 -> {465}; 464 -> {478};
465 -> {466 467}; 465 -> {466};
466 -> {480}; 466 -> {467};
467 -> {468}; 467 -> {468};
468 -> {469}; 468 -> {469};
469 -> {470}; 469 -> {470};
@@ -1245,86 +1243,86 @@ digraph boundSmartcastsInBranches_kt {
477 -> {478}; 477 -> {478};
478 -> {479}; 478 -> {479};
479 -> {480}; 479 -> {480};
480 -> {481};
481 -> {482};
subgraph cluster_92 { subgraph cluster_92 {
color=red color=red
483 [label="Enter function test_9" style="filled" fillcolor=red]; 481 [label="Enter function test_9" style="filled" fillcolor=red];
subgraph cluster_93 { subgraph cluster_93 {
color=blue color=blue
484 [label="Enter block"]; 482 [label="Enter block"];
485 [label="Const: Null(null)"]; 483 [label="Const: Null(null)"];
486 [label="Variable declaration: lvar a: R|kotlin/String?|"]; 484 [label="Variable declaration: lvar a: R|kotlin/String?|"];
487 [label="Variable declaration: lval b: R|kotlin/String?|"]; 485 [label="Variable declaration: lval b: R|kotlin/String?|"];
subgraph cluster_94 { subgraph cluster_94 {
color=blue color=blue
488 [label="Enter when"]; 486 [label="Enter when"];
subgraph cluster_95 { subgraph cluster_95 {
color=blue color=blue
489 [label="Enter when branch condition "]; 487 [label="Enter when branch condition "];
490 [label="Access variable R|<local>/a|"]; 488 [label="Access variable R|<local>/a|"];
491 [label="Const: Null(null)"]; 489 [label="Const: Null(null)"];
492 [label="Equality operator !="]; 490 [label="Equality operator !="];
493 [label="Exit when branch condition"]; 491 [label="Exit when branch condition"];
} }
subgraph cluster_96 { subgraph cluster_96 {
color=blue color=blue
494 [label="Enter when branch condition else"]; 492 [label="Enter when branch condition else"];
495 [label="Exit when branch condition"]; 493 [label="Exit when branch condition"];
} }
496 [label="Enter when branch result"]; 494 [label="Enter when branch result"];
subgraph cluster_97 { subgraph cluster_97 {
color=blue color=blue
497 [label="Enter block"]; 495 [label="Enter block"];
498 [label="Access variable R|<local>/a|"]; 496 [label="Access variable R|<local>/a|"];
499 [label="Smart cast: R|<local>/a|"]; 497 [label="Smart cast: R|<local>/a|"];
500 [label="Assignment: R|<local>/b|"]; 498 [label="Assignment: R|<local>/b|"];
501 [label="Exit block"]; 499 [label="Exit block"];
} }
502 [label="Exit when branch result"]; 500 [label="Exit when branch result"];
503 [label="Enter when branch result"]; 501 [label="Enter when branch result"];
subgraph cluster_98 { subgraph cluster_98 {
color=blue color=blue
504 [label="Enter block"]; 502 [label="Enter block"];
505 [label="Access variable R|<local>/a|"]; 503 [label="Access variable R|<local>/a|"];
506 [label="Smart cast: R|<local>/a|"]; 504 [label="Smart cast: R|<local>/a|"];
507 [label="Assignment: R|<local>/b|"]; 505 [label="Assignment: R|<local>/b|"];
508 [label="Exit block"]; 506 [label="Exit block"];
} }
509 [label="Exit when branch result"]; 507 [label="Exit when branch result"];
510 [label="Exit when"]; 508 [label="Exit when"];
} }
511 [label="Access variable R|<local>/b|"]; 509 [label="Access variable R|<local>/b|"];
512 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"]; 510 [label="Access variable R|kotlin/String.length<Inapplicable(UNSAFE_CALL): kotlin/String.length>#|"];
subgraph cluster_99 { subgraph cluster_99 {
color=blue color=blue
513 [label="Enter when"]; 511 [label="Enter when"];
subgraph cluster_100 { subgraph cluster_100 {
color=blue color=blue
514 [label="Enter when branch condition "]; 512 [label="Enter when branch condition "];
515 [label="Access variable R|<local>/a|"]; 513 [label="Access variable R|<local>/a|"];
516 [label="Const: Null(null)"]; 514 [label="Const: Null(null)"];
517 [label="Equality operator !="]; 515 [label="Equality operator !="];
518 [label="Exit when branch condition"]; 516 [label="Exit when branch condition"];
} }
519 [label="Synthetic else branch"]; 517 [label="Synthetic else branch"];
520 [label="Enter when branch result"]; 518 [label="Enter when branch result"];
subgraph cluster_101 { subgraph cluster_101 {
color=blue color=blue
521 [label="Enter block"]; 519 [label="Enter block"];
522 [label="Access variable R|<local>/b|"]; 520 [label="Access variable R|<local>/b|"];
523 [label="Smart cast: R|<local>/b|"]; 521 [label="Smart cast: R|<local>/b|"];
524 [label="Access variable R|kotlin/String.length|"]; 522 [label="Access variable R|kotlin/String.length|"];
525 [label="Exit block"]; 523 [label="Exit block"];
} }
526 [label="Exit when branch result"]; 524 [label="Exit when branch result"];
527 [label="Exit when"]; 525 [label="Exit when"];
} }
528 [label="Exit block"]; 526 [label="Exit block"];
} }
529 [label="Exit function test_9" style="filled" fillcolor=red]; 527 [label="Exit function test_9" style="filled" fillcolor=red];
} }
481 -> {482};
482 -> {483};
483 -> {484}; 483 -> {484};
484 -> {485}; 484 -> {485};
485 -> {486}; 485 -> {486};
@@ -1333,18 +1331,18 @@ digraph boundSmartcastsInBranches_kt {
488 -> {489}; 488 -> {489};
489 -> {490}; 489 -> {490};
490 -> {491}; 490 -> {491};
491 -> {492}; 491 -> {492 501};
492 -> {493}; 492 -> {493};
493 -> {494 503}; 493 -> {494};
494 -> {495}; 494 -> {495};
495 -> {496}; 495 -> {496};
496 -> {497}; 496 -> {497};
497 -> {498}; 497 -> {498};
498 -> {499}; 498 -> {499};
499 -> {500}; 499 -> {500};
500 -> {501}; 500 -> {508};
501 -> {502}; 501 -> {502};
502 -> {510}; 502 -> {503};
503 -> {504}; 503 -> {504};
504 -> {505}; 504 -> {505};
505 -> {506}; 505 -> {506};
@@ -1358,10 +1356,10 @@ digraph boundSmartcastsInBranches_kt {
513 -> {514}; 513 -> {514};
514 -> {515}; 514 -> {515};
515 -> {516}; 515 -> {516};
516 -> {517}; 516 -> {517 518};
517 -> {518}; 517 -> {525};
518 -> {519 520}; 518 -> {519};
519 -> {527}; 519 -> {520};
520 -> {521}; 520 -> {521};
521 -> {522}; 521 -> {522};
522 -> {523}; 522 -> {523};
@@ -1369,7 +1367,5 @@ digraph boundSmartcastsInBranches_kt {
524 -> {525}; 524 -> {525};
525 -> {526}; 525 -> {526};
526 -> {527}; 526 -> {527};
527 -> {528};
528 -> {529};
} }
@@ -359,17 +359,16 @@ digraph smartcastToNothing_kt {
134 [label="Enter block"]; 134 [label="Enter block"];
135 [label="Access variable R|<local>/a|"]; 135 [label="Access variable R|<local>/a|"];
136 [label="Smart cast: R|<local>/a|"]; 136 [label="Smart cast: R|<local>/a|"];
137 [label="Stub" style="filled" fillcolor=gray]; 137 [label="Access variable R|kotlin/String.length|"];
138 [label="Access variable R|kotlin/String.length|" style="filled" fillcolor=gray]; 138 [label="Variable declaration: lval b: R|kotlin/Int|"];
139 [label="Variable declaration: lval b: R|kotlin/Int|" style="filled" fillcolor=gray]; 139 [label="Exit block"];
140 [label="Exit block" style="filled" fillcolor=gray];
} }
141 [label="Exit when branch result" style="filled" fillcolor=gray]; 140 [label="Exit when branch result"];
142 [label="Exit when"]; 141 [label="Exit when"];
} }
143 [label="Exit block"]; 142 [label="Exit block"];
} }
144 [label="Exit function test_1" style="filled" fillcolor=red]; 143 [label="Exit function test_1" style="filled" fillcolor=red];
} }
108 -> {109}; 108 -> {109};
109 -> {110}; 109 -> {110};
@@ -395,17 +394,16 @@ digraph smartcastToNothing_kt {
129 -> {130}; 129 -> {130};
130 -> {131}; 130 -> {131};
131 -> {132 133}; 131 -> {132 133};
132 -> {142}; 132 -> {141};
133 -> {134}; 133 -> {134};
134 -> {135}; 134 -> {135};
135 -> {136}; 135 -> {136};
136 -> {137} [style=dotted]; 136 -> {137};
137 -> {138} [style=dotted]; 137 -> {138};
138 -> {139} [style=dotted]; 138 -> {139};
139 -> {140} [style=dotted]; 139 -> {140};
140 -> {141} [style=dotted]; 140 -> {141};
141 -> {142} [style=dotted]; 141 -> {142};
142 -> {143}; 142 -> {143};
143 -> {144};
} }
@@ -1159,13 +1159,8 @@ class ControlFlowGraphBuilder {
} }
fun exitSmartCastExpression(smartCastExpression: FirSmartCastExpression): SmartCastExpressionExitNode { fun exitSmartCastExpression(smartCastExpression: FirSmartCastExpression): SmartCastExpressionExitNode {
val returnsNothing = smartCastExpression.hasNothingType
val node = createSmartCastExitNode(smartCastExpression) val node = createSmartCastExitNode(smartCastExpression)
if (returnsNothing) { addNewSimpleNode(node)
addNonSuccessfullyTerminatingNode(node)
} else {
addNewSimpleNode(node)
}
return node return node
} }
@@ -78,7 +78,7 @@ fun case_7() {
// TESTCASE NUMBER: 8 // TESTCASE NUMBER: 8
fun case_8(x: TypealiasString) { fun case_8(x: TypealiasString) {
if (<!SENSELESS_COMPARISON!>x == null<!> && <!SENSELESS_COMPARISON!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString & kotlin.Nothing")!>x<!> == null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString")!>x<!> if (<!SENSELESS_COMPARISON!>x == null<!> && <!SENSELESS_COMPARISON!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString & kotlin.Nothing")!>x<!> == null<!>) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString & kotlin.Nothing")!>x<!>
} }
// TESTCASE NUMBER: 9 // TESTCASE NUMBER: 9
@@ -244,7 +244,7 @@ fun case_12(x: TypealiasNullableString, y: TypealiasNullableString, z1: Nothing?
// TESTCASE NUMBER: 13 // TESTCASE NUMBER: 13
fun case_13(x: EmptyClass12_48?, z: Nothing?) = fun case_13(x: EmptyClass12_48?, z: Nothing?) =
if (x == z || <!SENSELESS_COMPARISON!>x === z<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>== z<!><!>) { if (x == z || <!SENSELESS_COMPARISON!>x === z<!> && <!SENSELESS_COMPARISON!>x == z<!>) {
throw Exception() throw Exception()
} else { } else {
<!DEBUG_INFO_EXPRESSION_TYPE("othertypes.EmptyClass12_48? & othertypes.EmptyClass12_48")!>x<!> <!DEBUG_INFO_EXPRESSION_TYPE("othertypes.EmptyClass12_48? & othertypes.EmptyClass12_48")!>x<!>
@@ -289,7 +289,7 @@ fun case_14() {
// TESTCASE NUMBER: 15 // TESTCASE NUMBER: 15
fun case_15(x: TypealiasNullableString) { fun case_15(x: TypealiasNullableString) {
val y = null val y = null
val <!UNUSED_VARIABLE!>z<!> = if (x === null || <!SENSELESS_COMPARISON!>y == x<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>=== y<!><!> || <!SENSELESS_COMPARISON!>null === x<!>) "" else { val <!UNUSED_VARIABLE!>z<!> = if (x === null || <!SENSELESS_COMPARISON!>y == x<!> && <!SENSELESS_COMPARISON!>x === y<!> || <!SENSELESS_COMPARISON!>null === x<!>) "" else {
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString & kotlin.String")!>x<!> <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString & kotlin.String")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString & kotlin.String")!>x<!>.equals(null) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString & kotlin.String")!>x<!>.equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString & kotlin.String")!>x<!>.propT <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableString & kotlin.String")!>x<!>.propT
@@ -310,7 +310,7 @@ fun case_16() {
if (<!SENSELESS_COMPARISON!>x !== y<!>) { if (<!SENSELESS_COMPARISON!>x !== y<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing & kotlin.Nothing")!>x<!> <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing & kotlin.Nothing")!>x<!>
<!UNREACHABLE_CODE!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing & kotlin.Nothing")!>x<!>.hashCode()<!> <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing & kotlin.Nothing")!>x<!>.hashCode()
} }
} }
@@ -722,7 +722,7 @@ fun case_36(x: Any) {
if (<!SENSELESS_COMPARISON!>x == z<!>) { if (<!SENSELESS_COMPARISON!>x == z<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Nothing")!>x<!> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Nothing")!>x<!>
<!UNREACHABLE_CODE!><!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Nothing")!>x<!>.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!><!> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any & kotlin.Nothing")!>x<!>.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!>
} }
} }
@@ -744,7 +744,7 @@ fun case_38() {
if (<!SENSELESS_COMPARISON!>Object.prop_2 != z<!>) if (<!SENSELESS_COMPARISON!>Object.prop_2 != z<!>)
else { else {
Object.prop_2 Object.prop_2
<!UNREACHABLE_CODE!>Object.prop_2.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!><!> Object.prop_2.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!>
} }
} }
@@ -918,7 +918,7 @@ fun case_51() {
val x: TypealiasNullableNothing = null val x: TypealiasNullableNothing = null
val z: Nothing? = null val z: Nothing? = null
if (<!SENSELESS_COMPARISON!>x === z<!> || <!SENSELESS_COMPARISON!>z <!UNREACHABLE_CODE!>==<!> x<!> && <!SENSELESS_COMPARISON, UNREACHABLE_CODE!>x == z<!> || false || false || false) { if (<!SENSELESS_COMPARISON!>x === z<!> || <!SENSELESS_COMPARISON!>z == x<!> && <!SENSELESS_COMPARISON!>x == z<!> || false || false || false) {
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!> <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!>.hashCode() <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNullableNothing")!>x<!>.hashCode()
} }
@@ -1002,7 +1002,7 @@ fun case_57(a: (() -> Unit)) {
if (<!SENSELESS_COMPARISON!>a == z<!>) { if (<!SENSELESS_COMPARISON!>a == z<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function0<kotlin.Unit> & kotlin.Nothing")!>a<!> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function0<kotlin.Unit> & kotlin.Nothing")!>a<!>
<!UNREACHABLE_CODE!><!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function0<kotlin.Unit> & kotlin.Nothing")!>a<!>.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!><!> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function0<kotlin.Unit> & kotlin.Nothing")!>a<!>.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>java<!>
} }
} }
@@ -48,8 +48,8 @@ fun case_1(x: Any?) {
* ISSUES: KT-28159 * ISSUES: KT-28159
*/ */
fun case_2(x: Nothing?) { fun case_2(x: Nothing?) {
if (<!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>!== null<!><!>) { if (<!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x !== null<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing?")!>x<!> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing? & kotlin.Nothing")!>x<!>
} }
} }
@@ -90,17 +90,17 @@ fun case_4(x: Char?) {
fun case_5() { fun case_5() {
val x: Unit? = null val x: Unit? = null
if (x !== null || <!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>!== null<!><!> || <!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>!== null<!><!>) { if (x !== null || <!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x !== null<!> || <!SENSELESS_COMPARISON!>x !== null<!> && <!SENSELESS_COMPARISON!>x !== null<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!> <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!><!UNSAFE_CALL!>.<!>equals(null) <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.propT <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.propT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!><!UNSAFE_CALL!>.<!>propAny <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.propAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.propNullableT <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.propNullableT
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.propNullableAny <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.propNullableAny
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.funT() <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.funT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!><!UNSAFE_CALL!>.<!>funAny() <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.funAny()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.funNullableT() <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.funNullableT()
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit?")!>x<!>.funNullableAny() <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Unit? & kotlin.Unit")!>x<!>.funNullableAny()
} }
} }
@@ -274,7 +274,7 @@ fun case_14() {
// TESTCASE NUMBER: 15 // TESTCASE NUMBER: 15
fun case_15(x: TypealiasString?) { fun case_15(x: TypealiasString?) {
<!CAN_BE_VAL!>var<!> y = null <!CAN_BE_VAL!>var<!> y = null
val <!UNUSED_VARIABLE!>t<!> = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>if (x === null || <!SENSELESS_COMPARISON!>x == y<!> && <!SENSELESS_COMPARISON!>x <!UNREACHABLE_CODE!>=== y<!><!>) "" else { val <!UNUSED_VARIABLE!>t<!> = <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.String")!>if (x === null || <!SENSELESS_COMPARISON!>x == y<!> && <!SENSELESS_COMPARISON!>x === y<!>) "" else {
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString? & kotlin.String")!>x<!>.equals(null) <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString? & kotlin.String")!>x<!>.equals(null)
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString? & kotlin.String")!>x<!>.propT <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString? & kotlin.String")!>x<!>.propT
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString? & kotlin.String")!>x<!>.propAny <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasString? & kotlin.String")!>x<!>.propAny
@@ -295,7 +295,7 @@ fun case_16() {
if (<!SENSELESS_COMPARISON!>x != null<!> || <!SENSELESS_COMPARISON!>x !== null<!> || <!SENSELESS_COMPARISON!>x != y<!>) { if (<!SENSELESS_COMPARISON!>x != null<!> || <!SENSELESS_COMPARISON!>x !== null<!> || <!SENSELESS_COMPARISON!>x != y<!>) {
<!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNothing? & kotlin.Nothing")!>x<!> <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNothing? & kotlin.Nothing")!>x<!>
<!UNREACHABLE_CODE!><!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNothing? & kotlin.Nothing")!>x<!>.hashCode()<!> <!DEBUG_INFO_EXPRESSION_TYPE("TypealiasNothing? & kotlin.Nothing")!>x<!>.hashCode()
} }
} }