aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-03-26 18:06:50 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-11-18 11:37:35 +0100
commit94d286e85e8aedb843bddf807a59bfc834e7b44a (patch)
tree434111c0c588233072a64d6174b7194e2e4c3360
parentc0229b5ce35752c7fd4a888b6351eb9a4fc20e66 (diff)
downloadsparse-dev-94d286e85e8aedb843bddf807a59bfc834e7b44a.tar.gz
fix linearize_inc_dec() with floats
Using the pre or post increment or decrement operator on floating-point values mix the addition of a floating-point value with an *integral* constant 1 or -1. Fix this by checking if we're dealing with fp or not and using the proper fp constants (1.0 or -1.0) if it is the case. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--linearize.c18
-rw-r--r--validation/inc-dec-float.c13
2 files changed, 29 insertions, 2 deletions
diff --git a/linearize.c b/linearize.c
index fedd9e09..b4eb06c1 100644
--- a/linearize.c
+++ b/linearize.c
@@ -987,6 +987,18 @@ static pseudo_t add_setval(struct entrypoint *ep, struct symbol *ctype, struct e
return target;
}
+static pseudo_t add_setfval(struct entrypoint *ep, struct symbol *ctype, long double fval)
+{
+ struct instruction *insn = alloc_typed_instruction(OP_SETVAL, ctype);
+ struct expression *expr = alloc_expression(insn->pos, EXPR_FVALUE);
+ pseudo_t target = alloc_pseudo(insn);
+ insn->target = target;
+ insn->val = expr;
+ expr->fvalue = fval;
+ add_one_insn(ep, insn);
+ return target;
+}
+
static pseudo_t add_symbol_address(struct entrypoint *ep, struct symbol *sym)
{
struct instruction *insn = alloc_instruction(OP_SYMADDR, bits_in_pointer);
@@ -1025,7 +1037,6 @@ static pseudo_t linearize_access(struct entrypoint *ep, struct expression *expr)
return value;
}
-/* FIXME: FP */
static pseudo_t linearize_inc_dec(struct entrypoint *ep, struct expression *expr, int postop)
{
struct access_data ad = { NULL, };
@@ -1036,7 +1047,10 @@ static pseudo_t linearize_inc_dec(struct entrypoint *ep, struct expression *expr
return VOID;
old = linearize_load_gen(ep, &ad);
- one = value_pseudo(expr->op_value);
+ if (is_float_type(expr->ctype))
+ one = add_setfval(ep, expr->ctype, expr->op_value);
+ else
+ one = value_pseudo(expr->op_value);
new = add_binary_op(ep, expr->ctype, op, old, one);
linearize_store_gen(ep, new, &ad);
finish_address_gen(ep, &ad);
diff --git a/validation/inc-dec-float.c b/validation/inc-dec-float.c
new file mode 100644
index 00000000..3cac8f3e
--- /dev/null
+++ b/validation/inc-dec-float.c
@@ -0,0 +1,13 @@
+double fincpre(double a) { ++a; return a; }
+double fdecpre(double a) { --a; return a; }
+double fincpost(double a) { a++; return a; }
+double fdecpost(double a) { a--; return a; }
+
+/*
+ * check-name: float inc & dec
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ *
+ * check-output-excludes: \\$1$
+ * check-output-excludes: \\$-1$
+ */