A CIL Tutorial - Department of Computer Science - ETH Zürich
A CIL Tutorial - Department of Computer Science - ETH Zürich A CIL Tutorial - Department of Computer Science - ETH Zürich
CHAPTER 3. DATAFLOW ANALYSIS 22 static analysis. Now is a good time to take a look in dataflow.mli at the signature of the module that we'll be implementing, and what the functions of the module mean. Additionally, the Dataflow module is well documented in the main CIL documentation. 3.1 tut3.ml The dataow analysis here is a common textbook example for abstract interpretation, an even/odd analysis. First, we'll dene types and operations over the abstract state of the program. Then, we'll apply the functor. Following this, we'll write some boilerplate code for accessing the results of the analysis in an AST visitor. It should be straightforward to repurpose the code in this tutorial for many other kinds of dataow analysis, so feel free to use it as a starting point. For dataow analysis in the backwards direction, there is also a BackwardsDataFlow functor in the Dataflow module. module IH = Inthash (∗ An int → α hashtable library ∗) module DF = Dataflow (∗ CIL's dataow analysis library ∗) When debug is true, the dataow library emints out lots of debugging information. let debug = ref false 3.1.1 Type Denitions The abstract state for the analysis is a mapping from local variables of integral type to one of the oekind constructors. When a variable is mapped to one of these kinds, it has the following meaning: • Top The variable could be either odd or even. • Even The variable is an even integer. • Odd The variable is an odd integer. • Bottom The variable is uninitialized. type oekind = Top | Odd | Even | Bottom We'll use association lists to represent the mapping. An element of the mapping for a variable vi : varinfo is like: (vi.vid, (vi, kind)). We'll also need some utility functions for examining and manipulating the mappings.
CHAPTER 3. DATAFLOW ANALYSIS 23 Coding Hint: Whenever you dene a new type t, write a string of t function, and if it makes sense, a t of string function as well. Here, we have to in order to implement one of the functions we need for the ForwardsTransfer signature, but it's also a good idea in general for at least two reasons. First, they come in handy for debugging, and second, they give you a sense of how easy the types you've dened will be to program with. type varmap = int × (varinfo × oekind) let id of vm (vm : varmap) : int = fst vm let vi of vm (vm : varmap) : varinfo = vm | > snd | > fst let kind of vm (vm : varmap) : oekind = vm | > snd | > snd 3.1.2 Functions for pretty printing the state One of the functions we'll need to dene for the ForwardsDataFlow functor is a function to prettyprint the abstract state. In particular, we must dene a function that turns the abstract state into an instance of type Pretty.doc. Functions for constructing objects of this type are dened in the module Pretty in pretty.ml. For now, though, we'll just turn our abstract state into an OCaml string, and then use the function Pretty.text : string → doc to obtain a doc. let string of oekind (k : oekind) : string = match k with | Top → "Top" | Odd → "Odd" | Even → "Even" | Bottom → "Bottom" The string of varmap function converts a varmap tuple to a string: let string of varmap (vm : varmap) : string = let vi = vi of vm vm in "("¢vi.vname¢", "¢(vm | > kind of vm | > string of oekind)¢")" The string of varmap list converts a list of varmaps into a comma-separated list: let string of varmap list (vml : varmap list) : string = vml |> L.map string of varmap |> String.concat ", "
- Page 1 and 2: A CIL Tutorial Using CIL for langua
- Page 3 and 4: Contents Preface 4 Introduction 5 0
- Page 5 and 6: CONTENTS 3 13 Whole-program Analysi
- Page 7 and 8: Introduction The C Intermediate Lan
- Page 9 and 10: References [1] clang: a C language
- Page 11 and 12: CHAPTER 0. OVERVIEW AND ORGANIZATIO
- Page 13 and 14: Chapter 1 The AST The Concrete Synt
- Page 15 and 16: CHAPTER 1. THE AST 13 1.2 Printing
- Page 17 and 18: References [1] Andrew W. Appel. Mod
- Page 19 and 20: CHAPTER 2. VISITING THE AST 17 open
- Page 21 and 22: CHAPTER 2. VISITING THE AST 19 $ ci
- Page 23: Chapter 3 Dataow Analysis Dataow An
- Page 27 and 28: CHAPTER 3. DATAFLOW ANALYSIS 25 let
- Page 29 and 30: CHAPTER 3. DATAFLOW ANALYSIS 27 and
- Page 31 and 32: CHAPTER 3. DATAFLOW ANALYSIS 29 let
- Page 33 and 34: CHAPTER 3. DATAFLOW ANALYSIS 31 DoC
- Page 35 and 36: CHAPTER 3. DATAFLOW ANALYSIS 33 tes
- Page 37 and 38: References [1] Aws Albarghouthi, Ra
- Page 39 and 40: CHAPTER 4. INSTRUMENTATION 37 type
- Page 41 and 42: CHAPTER 4. INSTRUMENTATION 39 metho
- Page 43 and 44: CHAPTER 4. INSTRUMENTATION 41 $ cil
- Page 45 and 46: CHAPTER 5. INTERPRETED CONSTRUCTORS
- Page 47 and 48: CHAPTER 5. INTERPRETED CONSTRUCTORS
- Page 49 and 50: Chapter 6 Overriding Functions When
- Page 51 and 52: CHAPTER 6. OVERRIDING FUNCTIONS 49
- Page 53 and 54: References [1] Kumar Avijit, Pratee
- Page 55 and 56: CHAPTER 7. TYPE QUALIFIERS 53 let c
- Page 57 and 58: CHAPTER 7. TYPE QUALIFIERS 55 let w
- Page 59 and 60: CHAPTER 7. TYPE QUALIFIERS 57 $ cil
- Page 61 and 62: Chapter 8 Dependant Type Qualiers O
- Page 63 and 64: CHAPTER 8. DEPENDANT TYPE QUALIFIER
- Page 65 and 66: CHAPTER 8. DEPENDANT TYPE QUALIFIER
- Page 67 and 68: CHAPTER 8. DEPENDANT TYPE QUALIFIER
- Page 69 and 70: CHAPTER 8. DEPENDANT TYPE QUALIFIER
- Page 71 and 72: CHAPTER 8. DEPENDANT TYPE QUALIFIER
- Page 73 and 74: Chapter 9 Type Qualier Inference In
CHAPTER 3. DATAFLOW ANALYSIS 23<br />
Coding Hint: Whenever you dene a new type t, write a string <strong>of</strong> t function,<br />
and if it makes sense, a t <strong>of</strong> string function as well. Here, we have to<br />
in order to implement one <strong>of</strong> the functions we need for the ForwardsTransfer<br />
signature, but it's also a good idea in general for at least two reasons. First,<br />
they come in handy for debugging, and second, they give you a sense <strong>of</strong> how<br />
easy the types you've dened will be to program with.<br />
type varmap = int × (varinfo × oekind)<br />
let id <strong>of</strong> vm (vm : varmap) : int = fst vm<br />
let vi <strong>of</strong> vm (vm : varmap) : varinfo = vm | > snd | > fst<br />
let kind <strong>of</strong> vm (vm : varmap) : oekind = vm | > snd | > snd<br />
3.1.2 Functions for pretty printing the state<br />
One <strong>of</strong> the functions we'll need to dene for the ForwardsDataFlow functor is a function to prettyprint<br />
the abstract state. In particular, we must dene a function that turns the abstract state into<br />
an instance <strong>of</strong> type Pretty.doc. Functions for constructing objects <strong>of</strong> this type are dened in the<br />
module Pretty in pretty.ml. For now, though, we'll just turn our abstract state into an OCaml<br />
string, and then use the function Pretty.text : string → doc to obtain a doc.<br />
let string <strong>of</strong> oekind (k : oekind) : string =<br />
match k with<br />
| Top → "Top"<br />
| Odd → "Odd"<br />
| Even → "Even"<br />
| Bottom → "Bottom"<br />
The string <strong>of</strong> varmap function converts a varmap tuple to a string:<br />
let string <strong>of</strong> varmap (vm : varmap) : string =<br />
let vi = vi <strong>of</strong> vm vm in<br />
"("¢vi.vname¢", "¢(vm | > kind <strong>of</strong> vm | > string <strong>of</strong> oekind)¢")"<br />
The string <strong>of</strong> varmap list converts a list <strong>of</strong> varmaps into a comma-separated list:<br />
let string <strong>of</strong> varmap list (vml : varmap list) : string =<br />
vml<br />
|> L.map string <strong>of</strong> varmap<br />
|> String.concat ", "