Christian Gram Kalhauge
What does it mean for two variables to be dependent?
What is the primary problem when doing unbounded static analysis?
Why do we need a widening operator?
@Case("(0) -> ok")
@Case("(1) -> ok")
public static int safeDivByN(int n) {
if (n != 0) {
return 1 / n;
}
return 0;
}| Offset | Instruction | Abstract State |
|---|---|---|
000 | load:I 0 | |
001 | ifz eq 6 | |
002 | push:I 1 | |
003 | load:I 0 | |
004 | binary:I div | |
005 | return:I | |
006 | push:I 0 | |
007 | return:I |
| Offset | Instruction | Abstract State |
|---|---|---|
000 | load:I 0 | |
001 | ifz eq 6 | |
002 | push:I 1 | |
003 | load:I 0 | |
004 | binary:I div | |
005 | return:I | |
006 | push:I 0 | |
007 | return:I |
@Case("(0, 0) -> ok")
@Case("(1, 1) -> ok")
public static int safeDivAByB(int a, int b) {
if (a >= 0) {
if (b > a) {
return a / b
}
}
return 0;
}def manystep(sts : StateSet[A]) -> Iteratable[A | str]:
...final = {}
sts = A.initialstate_from_method(methodid)
for i in range(MAX_STEPS):
for s in manystep(sts):
if isinstance(s, str):
final.add(s)
else:
sts |= s
log.info(f"The following final states {final} is possible in {MAX_STEPS}")for pc, state in sts.per_instruction():
match bc[pc]:
case jvm.Binary(type=jvm.Int(), operant=opr):
...for ([va1, va2], after) for state.group(pop=[jvm.Int(), jvm.Int()]):
...for res in after.binary(opr, va1, va2):
match res with
case (va3, after):
yield after.frame.update(push=[va3], pc=pc+1)
case err:
yield errcase jvm.Ifz(condition=con, target=target):
for ([va1], after) for state.group(pop=[jvm.Int()]):
for res in after.binary(con, va1, 0):
match res:
case (True, after):
yield after.frame.update(pc=target)
case (False, after):
yield after.frame.update(pc=pc+1)
case err:
yield errGiven a function , that is monotone over then the minimal fixed point is the least st. means , were is applied times.
void example() {
int i = 0;
while (i >= 0) {
i = i + 1;
}
}An operator
class StateSet[A]:
per_inst : dict[PC, A]
needswork : set[PC]
def per_instruction(self):
for pc in self.needswork:
yield (pc, self.per_inst[pc])
# sts |= astate
def __ior__(self, astate):
old = self.per_inst[astate]
self.per_inst[astate.pc] |= astate
if old != self.per_inst[astate.pc]:
needswork.add(astate.pc)
...
void fn() {
int i = 0;
while (i < 100) {
i += 1;
}
// Many operations on i.
}What does it mean for two variables to be dependent?
What is the primary problem when doing unbounded static analysis?
Why do we need a widening operator?