@@ -467,7 +467,7 @@ One way to understand which functions form basic blocks is to consider the
467467successors of each instruction. If we have two instructions A and B, we say
468468that B is a * successor* of A if, after executing A, we can execute B without any
469469intervening instructions. For instance, in the example above, the loop
470- initialization statement ` unsigned long int i.1 = 1 ` is a successor of
470+ initialization statement ` unsigned int i.1 = 1 ` is a successor of
471471` unsigned long fac.1 = 1 ` . On the other hand, ` return fac.1 ` is not a successor
472472of ` unsigned long fac.1 = 1 ` : we always have to execute some other intermediate
473473statements to reach the return statement.
@@ -534,7 +534,7 @@ and \ref analyses-specific-analyses.
534534
535535While control flow graphs are already quite useful for static analysis,
536536some techniques benefit from a further transformation to a
537- representation know as ** static single assignment** , short ** SSA** . The
537+ representation known as ** static single assignment** , short ** SSA** . The
538538point of this step is to ensure that we can talk about the entire history
539539of assignments to a given variable. This is achieved by renaming
540540variables again: whenever we assign to a variable, we * clone* this
@@ -1218,23 +1218,24 @@ a map that associates both `fac` and `i` to "not 0".
12181218An abstract domain is a set $D$ (or, if you
12191219prefer, a data type) with the following properties:
12201220- There is a function merge that takes two elements of $D$ and returns
1221- an element of $D$. This function is associative (merge(x, merge(y,z))
1222- = merge(merge(x,y), z)), commutative (merge(x,y) = merge(y,x)) and
1223- idempotent (merge(x,x) = x).
1224- - There is an element bottom of $D$ such that merge(x, bottom) = x.
1221+ an element of $D$. This function is:
1222+ * ** associative** - ` (merge(x, merge(y,z)) = merge(merge(x,y), z)) ` ,
1223+ * ** commutative** - ` (merge(x,y) = merge(y,x)) ` and
1224+ * ** idempotent** ` (merge(x,x) = x) ` .
1225+ - There is an element bottom of $D$ such that ` merge(x, bottom) = x ` .
12251226
12261227Algebraically speaking, $D$ needs to be a semi-lattice.
12271228
12281229For our example, we use the following domain:
12291230- D contains the elements "bottom" (nothing is known),
12301231 "equals 0", "not 0" and "could be 0".
12311232
1232- - merge is defined as follows:
1233- merge(bottom, x) = x
1234- merge("could be 0", x) = "could be 0"
1235- merge(x,x) = x
1236- merge("equals 0", "not 0") = "could be 0"
1237- - bottom is bottom, obviously.
1233+ - ` merge ` is defined as follows:
1234+ * ` merge(bottom, x) ` = ` x `
1235+ * ` merge("could be 0", x) ` = ` "could be 0" `
1236+ * ` merge(x,x) = ` x`
1237+ * ` merge("equals 0", "not 0") ` = ` "could be 0" `
1238+ - ` bottom ` is bottom, obviously.
12381239It is easy but tedious to check that all conditions hold.
12391240
12401241The second ingredient we need are the ** abstract state transformers** .
@@ -1251,7 +1252,7 @@ case, the result is "could be 0".
12511252
12521253What if ` x ` and ` y ` are both "not 0"? In a mathematically ideal world,
12531254we would have ` x*y ` be non-zero as well. But in a C program,
1254- multiplication could overflow, yielding 0! So, to be correct, we have to
1255+ multiplication could * overflow* , yielding ` 0 ` . So, to be correct, we have to
12551256yield "could be 0" in this case.
12561257
12571258Finally, when ` x ` is bottom, we can just return whatever value we had
0 commit comments