commit fa7b4c4b8f076a6add45cdbc77f490f4a5023b43
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Wed Sep 21 14:18:47 2011 -0400
cpychecker: implement division
libcpychecker/refcounts.py | 33 ++++++++++++-------
.../absinterp/arithmetic/correct/input.c | 2 +
2 files changed, 23 insertions(+), 12 deletions(-)
---
diff --git a/libcpychecker/refcounts.py b/libcpychecker/refcounts.py
index 5ab617c..8d957f3 100644
--- a/libcpychecker/refcounts.py
+++ b/libcpychecker/refcounts.py
@@ -1724,14 +1724,20 @@ class MyState(State):
# % (exprcode, lhs, rhs))
return UnknownValue(stmt.lhs.type, stmt.loc)
+ def eval_binop_args(self, stmt):
+ rhs = stmt.rhs
+ a = self.eval_rvalue(rhs[0], stmt.loc)
+ b = self.eval_rvalue(rhs[1], stmt.loc)
+ log('a: %r', a)
+ log('b: %r', b)
+ return a, b
+
def eval_rhs(self, stmt):
log('eval_rhs(%s): %s', stmt, stmt.rhs)
rhs = stmt.rhs
+ # Handle arithmetic expressions:
if stmt.exprcode == gcc.PlusExpr:
- a = self.eval_rvalue(rhs[0], stmt.loc)
- b = self.eval_rvalue(rhs[1], stmt.loc)
- log('a: %r', a)
- log('b: %r', b)
+ a, b = self.eval_binop_args(stmt)
if isinstance(a, UnknownValue) or isinstance(b, UnknownValue):
return UnknownValue(stmt.lhs.type, stmt.loc)
if isinstance(a, ConcreteValue) and isinstance(b, ConcreteValue):
@@ -1744,10 +1750,7 @@ class MyState(State):
raise NotImplementedError("Don't know how to cope with addition of\n %r\nand\n %r\nat %s"
% (a, b, stmt.loc))
elif stmt.exprcode == gcc.MinusExpr:
- a = self.eval_rvalue(rhs[0], stmt.loc)
- b = self.eval_rvalue(rhs[1], stmt.loc)
- log('a: %r', a)
- log('b: %r', b)
+ a, b = self.eval_binop_args(stmt)
if isinstance(a, UnknownValue) or isinstance(b, UnknownValue):
return UnknownValue(stmt.lhs.type, stmt.loc)
if isinstance(a, ConcreteValue) and isinstance(b, ConcreteValue):
@@ -1758,16 +1761,22 @@ class MyState(State):
raise NotImplementedError("Don't know how to cope with subtraction of\n %r\nand\n %rat %s"
% (a, b, stmt.loc))
elif stmt.exprcode == gcc.MultExpr:
- a = self.eval_rvalue(rhs[0], stmt.loc)
- b = self.eval_rvalue(rhs[1], stmt.loc)
- log('a: %r', a)
- log('b: %r', b)
+ a, b = self.eval_binop_args(stmt)
if isinstance(a, UnknownValue) or isinstance(b, UnknownValue):
return UnknownValue(stmt.lhs.type, stmt.loc)
if isinstance(a, ConcreteValue) and isinstance(b, ConcreteValue):
return ConcreteValue(stmt.lhs.type, stmt.loc, a.value * b.value)
raise NotImplementedError("Don't know how to cope with multiplication of\n %r\nand\n %rat %s"
% (a, b, stmt.loc))
+ elif stmt.exprcode == gcc.TruncDivExpr:
+ a, b = self.eval_binop_args(stmt)
+ if isinstance(a, UnknownValue) or isinstance(b, UnknownValue):
+ return UnknownValue(stmt.lhs.type, stmt.loc)
+ if isinstance(a, ConcreteValue) and isinstance(b, ConcreteValue):
+ return ConcreteValue(stmt.lhs.type, stmt.loc,
+ a.value // b.value)
+ raise NotImplementedError("Don't know how to cope with division of\n %r\nand\n %rat %s"
+ % (a, b, stmt.loc))
elif stmt.exprcode == gcc.ComponentRef:
return self.eval_rvalue(rhs[0], stmt.loc)
elif stmt.exprcode == gcc.VarDecl:
diff --git a/tests/cpychecker/absinterp/arithmetic/correct/input.c b/tests/cpychecker/absinterp/arithmetic/correct/input.c
index 9da7555..eaafa48 100644
--- a/tests/cpychecker/absinterp/arithmetic/correct/input.c
+++ b/tests/cpychecker/absinterp/arithmetic/correct/input.c
@@ -33,6 +33,8 @@ test(void)
foo(i++);
foo(i++);
foo(i--);
+ foo(i * 2);
+ foo(i / 2);
return i;
}