The Penultimate Challenge: Bug report construction in the Clang - - PowerPoint PPT Presentation

the penultimate challenge bug report construction in the
SMART_READER_LITE
LIVE PREVIEW

The Penultimate Challenge: Bug report construction in the Clang - - PowerPoint PPT Presentation

The Penultimate Challenge: Bug report construction in the Clang Static Analyzer Kristf Umann dkszelethus@gmail.com Etvs Lornd University, Budapest Ericsson Hungary 2019. oct. 22. 2/38 Clear, precise bug reports are important One of


slide-1
SLIDE 1

The Penultimate Challenge: Bug report construction in the Clang Static Analyzer

Kristóf Umann dkszelethus@gmail.com

Eötvös Loránd University, Budapest Ericsson Hungary

  • 2019. oct. 22.
slide-2
SLIDE 2

2/38

slide-3
SLIDE 3

Clear, precise bug reports are important

One of the main selling points of Clang back in the day Not only wording, it requires a good infrastructure Tools without it are miserable to use

3/38

slide-4
SLIDE 4

Agenda

Path-sensitive analysis in the Clang Static Analyzer Current state of bug report construction Diffjculties, current state of research, future work

4/38

slide-5
SLIDE 5

Path-sensitive analysis in the Clang Static Analyzer

slide-6
SLIDE 6

The Clang Static Analyzer

It employs a variety of techniques to analyze C, C++, ObjectiveC, ObjectiveC++ code: AST matching CFG based analyses Symbolic execution

5/38

slide-7
SLIDE 7

Exploring paths of execution

Traverse the control fmow graph (CFG) of a function On branches, explore a path on which the condition is true, and one on which its false How does this work interprocedurally?

6/38

slide-8
SLIDE 8

Exploring paths of execution

Traverse the control fmow graph (CFG) of a function On branches, explore a path on which the condition is true, and one on which its false How does this work interprocedurally? Inlining!

6/38

slide-9
SLIDE 9

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-10
SLIDE 10

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-11
SLIDE 11

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-12
SLIDE 12

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-13
SLIDE 13

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-14
SLIDE 14

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-15
SLIDE 15

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-16
SLIDE 16

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-17
SLIDE 17

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-18
SLIDE 18

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-19
SLIDE 19

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-20
SLIDE 20

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

7/38

slide-21
SLIDE 21

[B5 (ENTRY)] [B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-22
SLIDE 22

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B4] int *x = 0; flag = 1; foo(); if (flag) flag == 1; x == nullptr; [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-23
SLIDE 23

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) flag == 1; x == nullptr; [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-24
SLIDE 24

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) flag == 1; x == nullptr; [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-25
SLIDE 25

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) flag ∈ (−∞, ∞); x == nullptr; [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-26
SLIDE 26

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) flag ∈ (−∞, ∞); x == nullptr; [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] [B0 (EXIT)] foo:

8/38

slide-27
SLIDE 27

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) flag ∈ (−∞, ∞); x == nullptr; [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-28
SLIDE 28

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B4] int *x = 0; flag = 1; foo(); if (flag) flag ∈ (−∞, ∞); x == nullptr; [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-29
SLIDE 29

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) flag == 0; x == nullptr; [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-30
SLIDE 30

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) flag == 0; x == nullptr; [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-31
SLIDE 31

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) flag == 0; x == nullptr; [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-32
SLIDE 32

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) flag ∈ (−∞, ∞); x == nullptr; [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-33
SLIDE 33

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) flag ∈ (−∞, ∞); x == nullptr; [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] [B0 (EXIT)] foo:

8/38

slide-34
SLIDE 34

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) flag ∈ (−∞, ∞); x == nullptr; [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-35
SLIDE 35

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) flag ∈ (−∞, ∞); x == nullptr; [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-36
SLIDE 36

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B1] *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞); x == nullptr; dereference of x! [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo:

8/38

slide-37
SLIDE 37

The ExplodedGraph

Contains everything the analyzer learned during symbolic execution All explored paths of execution Every symbolic value in every program state

9/38

slide-38
SLIDE 38

[B5 (ENTRY)] [B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-39
SLIDE 39

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-40
SLIDE 40

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-41
SLIDE 41

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-42
SLIDE 42

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-43
SLIDE 43

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-44
SLIDE 44

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-45
SLIDE 45

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-46
SLIDE 46

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-47
SLIDE 47

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-48
SLIDE 48

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-49
SLIDE 49

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-50
SLIDE 50

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-51
SLIDE 51

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-52
SLIDE 52

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-53
SLIDE 53

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-54
SLIDE 54

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-55
SLIDE 55

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-56
SLIDE 56

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-57
SLIDE 57

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-58
SLIDE 58

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-59
SLIDE 59

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-60
SLIDE 60

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-61
SLIDE 61

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-62
SLIDE 62

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-63
SLIDE 63

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-64
SLIDE 64

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-65
SLIDE 65

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-66
SLIDE 66

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-67
SLIDE 67

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-68
SLIDE 68

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr

10/38

slide-69
SLIDE 69

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] [B0 (EXIT)] main: [B1] flag = coin(); [B2 (ENTRY)] [B0 (EXIT)] foo: flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr flag = 0 x = nullptr

10/38

slide-70
SLIDE 70

There is always more to talk about...

Branches in the ExplodedGraph may happen far more often Representation of values, regions: symbols ExplodedGraphs are usually very-very large, and contain tremendous amount

  • f information

11/38

slide-71
SLIDE 71

There is always more to talk about...

Branches in the ExplodedGraph may happen far more often Representation of values, regions: symbols ExplodedGraphs are usually very-very large, and contain tremendous amount

  • f information

11/38

slide-72
SLIDE 72

There is always more to talk about...

Branches in the ExplodedGraph may happen far more often Representation of values, regions: symbols ExplodedGraphs are usually very-very large, and contain tremendous amount

  • f information

11/38

slide-73
SLIDE 73

Bug report construction

slide-74
SLIDE 74

Processing of the ExplodedGraph

Bugs are represented with error nodes The graph may contain several of them The goal is to explain the path to these nodes For each node, construct the shortest path from the root to the error node This is called a bug path

12/38

slide-75
SLIDE 75

Processing of the ExplodedGraph

Bugs are represented with error nodes The graph may contain several of them The goal is to explain the path to these nodes For each node, construct the shortest path from the root to the error node This is called a bug path

12/38

slide-76
SLIDE 76

Processing of the ExplodedGraph

Bugs are represented with error nodes The graph may contain several of them The goal is to explain the path to these nodes For each node, construct the shortest path from the root to the error node This is called a bug path

12/38

slide-77
SLIDE 77

flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr flag = 0 x = nullptr

13/38

slide-78
SLIDE 78

flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined (after the call to foo) flag ∈ (−∞, ∞) x = (heap allocated object) *x = undefined flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag ∈ (−∞, 0) ∪ (0, ∞) x = (heap allocated object) dereference of x! *x = 5 flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = (heap allocated object) *x = undefined flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag = 0 x = nullptr flag = 0 x = nullptr

13/38

slide-79
SLIDE 79

flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 }

14/38

slide-80
SLIDE 80

The ideal bug report

The goal is to generate a bug report from the bug path that is complete: contains every information necessary to understand how the bug

  • ccured

minimal: contains no unnecessary information

15/38

slide-81
SLIDE 81

Techniques used by the analyzer

2 techniques:

BugReporterVisitors Interestingness propagation

Visit the nodes of the bugpath from the error node to the root

16/38

slide-82
SLIDE 82

Techniques used by the analyzer

2 techniques:

BugReporterVisitors Interestingness propagation

Visit the nodes of the bugpath from the error node to the root

16/38

slide-83
SLIDE 83

Techniques used by the analyzer

2 techniques:

BugReporterVisitors Interestingness propagation

Visit the nodes of the bugpath from the error node to the root

16/38

slide-84
SLIDE 84

flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

17/38

slide-85
SLIDE 85

flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

<warning msg>

flag = 1 x = nullptr (after the call to foo) flag x = nullptr (after the call to foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag x = nullptr (after the call to foo) flag x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

<warning msg>

17/38

slide-86
SLIDE 86

flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

<diagnostic msg 4>

flag = 1 x = nullptr (after the call to foo) flag x = nullptr (after the call to foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

<diagnostic msg 4>

17/38

slide-87
SLIDE 87

flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

<diagnostic msg 3>

flag = 1 x = nullptr (after the call to foo) flag x = nullptr (after the call to foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag x = nullptr (after the call to foo) flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

<diagnostic msg 3>

17/38

slide-88
SLIDE 88

flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

<diagnostic msg 2>

flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag x = nullptr (after the call to foo) flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

<diagnostic msg 2>

17/38

slide-89
SLIDE 89

flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

<diagnostic msg 1>

flag = 1 x = nullptr (after the call to foo) flag x = nullptr (after the call to foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag x = nullptr (after the call to foo) flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

<diagnostic msg 1>

17/38

slide-90
SLIDE 90

BugReporterVisitors

An arbitrary number of visitors can be registered Their visitNode() is called on each node visit Visitors may create diagnostic messages about the node they are currently visiting Despite the misleading name, they are more like callbacks than visitors

18/38

slide-91
SLIDE 91

BugReporterVisitors

An arbitrary number of visitors can be registered Their visitNode() is called on each node visit Visitors may create diagnostic messages about the node they are currently visiting Despite the misleading name, they are more like callbacks than visitors

18/38

slide-92
SLIDE 92

BugReporterVisitors

An arbitrary number of visitors can be registered Their visitNode() is called on each node visit Visitors may create diagnostic messages about the node they are currently visiting Despite the misleading name, they are more like callbacks than visitors

18/38

slide-93
SLIDE 93

BugReporterVisitors

An arbitrary number of visitors can be registered Their visitNode() is called on each node visit Visitors may create diagnostic messages about the node they are currently visiting Despite the misleading name, they are more like callbacks than visitors

18/38

slide-94
SLIDE 94

Visitors

ConditionBRVisitor: Describes conditions of if branches, loops, conditional

  • perators etc.

FindLastStoreBRVisitor: Finds the last store to a given variable TrackControlDependencyCondBRVisitor

19/38

slide-95
SLIDE 95

Visitors

ConditionBRVisitor: Describes conditions of if branches, loops, conditional

  • perators etc.

FindLastStoreBRVisitor: Finds the last store to a given variable TrackControlDependencyCondBRVisitor

19/38

slide-96
SLIDE 96

Visitors

ConditionBRVisitor: Describes conditions of if branches, loops, conditional

  • perators etc.

FindLastStoreBRVisitor: Finds the last store to a given variable TrackControlDependencyCondBRVisitor

19/38

slide-97
SLIDE 97

TrackControlDependencyCondBRVisitor

Most recent addition, available in Clang 10.0.0 GSoC’19 project mentored by Artem Dergachev, Gábor Horváth and Ádám Balogh https://szelethus.github.io/gsoc2019/ Calculates control dependencies to points of interest Tells the analyzer to explain the conditions of control dependency blocks

20/38

slide-98
SLIDE 98

TrackControlDependencyCondBRVisitor

Most recent addition, available in Clang 10.0.0 GSoC’19 project mentored by Artem Dergachev, Gábor Horváth and Ádám Balogh https://szelethus.github.io/gsoc2019/ Calculates control dependencies to points of interest Tells the analyzer to explain the conditions of control dependency blocks

20/38

slide-99
SLIDE 99

TrackControlDependencyCondBRVisitor

Most recent addition, available in Clang 10.0.0 GSoC’19 project mentored by Artem Dergachev, Gábor Horváth and Ádám Balogh https://szelethus.github.io/gsoc2019/ Calculates control dependencies to points of interest Tells the analyzer to explain the conditions of control dependency blocks

20/38

slide-100
SLIDE 100

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

21/38

slide-101
SLIDE 101

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

21/38

slide-102
SLIDE 102

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

21/38

slide-103
SLIDE 103

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B1] *x = 5 [B0 (EXIT)] [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

21/38

slide-104
SLIDE 104

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

21/38

slide-105
SLIDE 105

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

21/38

slide-106
SLIDE 106

Interestingness propagation

During analysis, some symbolic regions or values may have been marked as ”interesting”. During bug report construction, propagate interestingness to entities that interact with an interesting entity Nodes in the bug path that do not desribe an interesting entity are pruned

22/38

slide-107
SLIDE 107

Interestingness propagation

During analysis, some symbolic regions or values may have been marked as ”interesting”. During bug report construction, propagate interestingness to entities that interact with an interesting entity Nodes in the bug path that do not desribe an interesting entity are pruned

22/38

slide-108
SLIDE 108

Interestingness propagation

During analysis, some symbolic regions or values may have been marked as ”interesting”. During bug report construction, propagate interestingness to entities that interact with an interesting entity Nodes in the bug path that do not desribe an interesting entity are pruned

22/38

slide-109
SLIDE 109

Combining Visitors and Interestingness

Expression value tracking! Mark the expression as interesting Register visitors to describe events related to it

FindLastStoreBRVisitor TrackControlDependencyCondBRVisitor ReturnVisitor UndefOrNullArgVisitor etc...

TrackControlDependencyCondBRVisitor does that as well

23/38

slide-110
SLIDE 110

Combining Visitors and Interestingness

Expression value tracking! Mark the expression as interesting Register visitors to describe events related to it

FindLastStoreBRVisitor TrackControlDependencyCondBRVisitor ReturnVisitor UndefOrNullArgVisitor etc...

TrackControlDependencyCondBRVisitor does that as well

23/38

slide-111
SLIDE 111

Combining Visitors and Interestingness

Expression value tracking! Mark the expression as interesting Register visitors to describe events related to it

FindLastStoreBRVisitor TrackControlDependencyCondBRVisitor ReturnVisitor UndefOrNullArgVisitor etc...

TrackControlDependencyCondBRVisitor does that as well

23/38

slide-112
SLIDE 112

Combining Visitors and Interestingness

Expression value tracking! Mark the expression as interesting Register visitors to describe events related to it

FindLastStoreBRVisitor TrackControlDependencyCondBRVisitor ReturnVisitor UndefOrNullArgVisitor etc...

TrackControlDependencyCondBRVisitor does that as well

23/38

slide-113
SLIDE 113

flag = 1 x = nullptr flag = 1 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr (after the call to foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 }

24/38

slide-114
SLIDE 114 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

25/38

slide-115
SLIDE 115 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

25/38

slide-116
SLIDE 116 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

25/38

slide-117
SLIDE 117 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

25/38

slide-118
SLIDE 118 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Stage 1: Visitor notes

25/38

slide-119
SLIDE 119 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x} The checker tracks x’s value

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x} The checker tracks x’s value

25/38

slide-120
SLIDE 120 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x} ConditionBRVisitor: As- suming ’flag’ is not equal to

note: Assuming flag is true

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x} ConditionBRVisitor: As- suming ’flag’ is not equal to

note: Assuming flag is true

25/38

slide-121
SLIDE 121 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true

TrackControlDependencyCond- BRVisitor tracks flag

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true

TrackControlDependencyCond- BRVisitor tracks flag

25/38

slide-122
SLIDE 122 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true

25/38

slide-123
SLIDE 123 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true

FindLastStoreBRVisitor: Value assigned to ’flag’

note: flag is assigned a value

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true

FindLastStoreBRVisitor: Value assigned to ’flag’

note: flag is assigned a value

25/38

slide-124
SLIDE 124 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value

25/38

slide-125
SLIDE 125 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value

25/38

slide-126
SLIDE 126 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value

ConditionBRVisitor: As- suming ’flag’ is 0

note: Assuming flag is false

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value

ConditionBRVisitor: As- suming ’flag’ is 0

note: Assuming flag is false

25/38

slide-127
SLIDE 127 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false

25/38

slide-128
SLIDE 128 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false

FindLastStoreBRVisitor is already satisfjed, no notes

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false

FindLastStoreBRVisitor is already satisfjed, no notes

25/38

slide-129
SLIDE 129 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false

25/38

slide-130
SLIDE 130 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false

25/38

slide-131
SLIDE 131 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false

FindLastStoreBRVisitor: ’x’ initialized to null pointer value

note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

Tracked variables: {x, flag}

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false

FindLastStoreBRVisitor: ’x’ initialized to null pointer value

note: x initialized to nullptr

25/38

slide-132
SLIDE 132 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false note: x initialized to nullptr

Stage 2: Non-visitor notes

25/38

slide-133
SLIDE 133 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

The warning message is sup- plied by the checker

warning: Nullptr dereference note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

The warning message is sup- plied by the checker

warning: Nullptr dereference note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false note: x initialized to nullptr

25/38

slide-134
SLIDE 134 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: flag is assigned a value note: Assuming flag is false note: x initialized to nullptr

25/38

slide-135
SLIDE 135 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true

Returning from ’foo’

note: Returning from foo note: flag is assigned a value note: Assuming flag is false note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true

Returning from ’foo’

note: Returning from foo note: flag is assigned a value note: Assuming flag is false note: x initialized to nullptr

25/38

slide-136
SLIDE 136 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Assuming flag is false note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Assuming flag is false note: x initialized to nullptr

25/38

slide-137
SLIDE 137 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value

Entering call from ’main’

note: Entered function from main note: Assuming flag is false note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value

Entering call from ’main’

note: Entered function from main note: Assuming flag is false note: x initialized to nullptr

25/38

slide-138
SLIDE 138 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main

Calling ’foo’

note: Calling foo note: Assuming flag is false note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main

Calling ’foo’

note: Calling foo note: Assuming flag is false note: x initialized to nullptr

25/38

slide-139
SLIDE 139 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: x initialized to nullptr

25/38

slide-140
SLIDE 140 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false

Returning from ’foo’

note: Returning from foo note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false

Returning from ’foo’

note: Returning from foo note: x initialized to nullptr

25/38

slide-141
SLIDE 141 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: Returning from foo note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: Returning from foo note: x initialized to nullptr

25/38

slide-142
SLIDE 142 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: Returning from foo

Entering call from ’main’

note: Entered function from main note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: Returning from foo

Entering call from ’main’

note: Entered function from main note: x initialized to nullptr

25/38

slide-143
SLIDE 143 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: Returning from foo note: Entered function from main

Calling ’foo’

note: Calling foo note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: Returning from foo note: Entered function from main

Calling ’foo’

note: Calling foo note: x initialized to nullptr

25/38

slide-144
SLIDE 144 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: Returning from foo note: Entered function from main note: Calling foo note: x initialized to nullptr

flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag x = nullptr (entering foo) flag x = nullptr flag x = nullptr flag x = nullptr (returning from foo) flag x = nullptr (returning from foo) flag x = nullptr flag x = nullptr flag x = nullptr flag x = nullptr dereference of x! flag x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: Returning from foo note: Entered function from main note: Calling foo note: x initialized to nullptr

25/38

slide-145
SLIDE 145 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: Returning from foo note: Entered function from main note: Calling foo note: x initialized to nullptr

Stage 3: Pruning

25/38

slide-146
SLIDE 146 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: Returning from foo note: Entered function from main note: Calling foo note: x initialized to nullptr

25/38

slide-147
SLIDE 147 flag = 1 x = nullptr (calling foo) (calling foo) (entering foo) flag = 1 x = nullptr (entering foo) flag = 1 x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag = 0 x = nullptr flag = 0 x = nullptr (calling foo) (calling foo) (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr (entering foo) flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr (returning from foo) flag ∈ (−∞, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x! flag ∈ (−∞, 0) ∪ (0, ∞) x = nullptr dereference of x!

warning: Nullptr dereference note: Assuming flag is true note: Returning from foo note: flag is assigned a value note: Entered function from main note: Calling foo note: Assuming flag is false note: x initialized to nullptr

25/38

slide-148
SLIDE 148

26/38

slide-149
SLIDE 149

27/38

slide-150
SLIDE 150

28/38

slide-151
SLIDE 151

Present problems, research

slide-152
SLIDE 152

Very hard to solve problems

Relevant information isn’t found in the bug path Ad absurdum, not even in the ExplodedGraph

29/38

slide-153
SLIDE 153

Very hard to solve problems

Relevant information isn’t found in the bug path Ad absurdum, not even in the ExplodedGraph

29/38

slide-154
SLIDE 154

30/38

slide-155
SLIDE 155

01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 }

31/38

slide-156
SLIDE 156

01 02 03 04 05 06 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 }

31/38

slide-157
SLIDE 157

01 02 03 04 05 06 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 printf("Nothing to see here!"); 14 foo(); 15 16 if (flag) 17 *x = 5; 18 }

31/38

slide-158
SLIDE 158

Reaching defjnitions analysis

An algorithm to fjnd a set of last stores (defjnitions) to a variable Regard all defjnitions to a variable as a point of interest https://reviews.llvm.org/D64991

32/38

slide-159
SLIDE 159

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

33/38

slide-160
SLIDE 160

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

33/38

slide-161
SLIDE 161

[B5 (ENTRY)] [B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

33/38

slide-162
SLIDE 162

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

33/38

slide-163
SLIDE 163

[B5 (ENTRY)] [B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B3] x = new int; [B2] foo(); if (flag) [B2] foo(); if (flag) [B1] *x = 5 [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

33/38

slide-164
SLIDE 164

[B5 (ENTRY)] [B4] int *x = 0; flag = 1; foo(); if (flag) [B3] x = new int; [B2] foo(); if (flag) [B1] *x = 5 [B1] *x = 5 [B0 (EXIT)] main: 01 int flag; 02 bool coin(); 03 04 void foo() { 05 flag = coin(); 06 } 07 08 int main() { 09 int *x = 0; 10 flag = 1; 11 foo(); 12 if (flag) 13 x = new int; 14 foo(); 15 16 if (flag) 17 *x = 5; 18 } foo: [B2 (ENTRY)] [B1] flag = coin(); [B0 (EXIT)]

33/38

slide-165
SLIDE 165

Problems with reaching defjnitions

Originally concieved for instructions Incredibly complex to implement for C, C++, etc... Doesn’t argue about aliasing Only works in a given CFG... Using visitors, its possible to make this algorithm semi-interprocedural

34/38

slide-166
SLIDE 166

Problems with reaching defjnitions

Originally concieved for instructions Incredibly complex to implement for C, C++, etc... Doesn’t argue about aliasing Only works in a given CFG... Using visitors, its possible to make this algorithm semi-interprocedural

34/38

slide-167
SLIDE 167

Conclusion

slide-168
SLIDE 168

Conclusion

Clear and precise bug reports are important The analyzer users callbacks (or visitors) and interestingness propagation to construct path-sensitive bug reports Problems that require arguing outside the bugpath, especially the ExplodedGraph are insanely diffjcult The analyzer gets better by the minute

35/38

slide-169
SLIDE 169

Conclusion

Clear and precise bug reports are important The analyzer users callbacks (or visitors) and interestingness propagation to construct path-sensitive bug reports Problems that require arguing outside the bugpath, especially the ExplodedGraph are insanely diffjcult The analyzer gets better by the minute

35/38

slide-170
SLIDE 170

Conclusion

Clear and precise bug reports are important The analyzer users callbacks (or visitors) and interestingness propagation to construct path-sensitive bug reports Problems that require arguing outside the bugpath, especially the ExplodedGraph are insanely diffjcult The analyzer gets better by the minute

35/38

slide-171
SLIDE 171

Conclusion

Clear and precise bug reports are important The analyzer users callbacks (or visitors) and interestingness propagation to construct path-sensitive bug reports Problems that require arguing outside the bugpath, especially the ExplodedGraph are insanely diffjcult The analyzer gets better by the minute

35/38

slide-172
SLIDE 172

36/38

slide-173
SLIDE 173

37/38

slide-174
SLIDE 174
slide-175
SLIDE 175

Questions?