[hackers] [scc] Add validation for float operations || Roberto E. Vargas Caballero

From: <git_AT_suckless.org>
Date: Wed, 2 Sep 2015 12:50:51 +0200 (CEST)

commit 42fd6480b200aab21dc5118050b8f4753cd25967
Author: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
AuthorDate: Wed Sep 2 11:41:05 2015 +0200
Commit: Roberto E. Vargas Caballero <k0ga_AT_shike2.com>
CommitDate: Wed Sep 2 12:43:02 2015 +0200

    Add validation for float operations

diff --git a/cc1/fold.c b/cc1/fold.c
index 43d511e..f282b6b 100644
--- a/cc1/fold.c
+++ b/cc1/fold.c
_AT_@ -23,12 +23,36 @@ addi(TINT l, TINT r, Type *tp)
 }
 
 static bool
+addf(TFLOAT l, TFLOAT r, Type *tp)
+{
+ struct limits *lim = getlimits(tp);
+ TFLOAT max = lim->max.f, min = lim->min.f;
+
+ if (l < 0 && r < 0 && l >= min - r ||
+ l == 0 ||
+ r == 0 ||
+ l < 0 && r > 0 ||
+ l > 0 && r < 0 ||
+ l > 0 && r > 0 && l <= max - r) {
+ return 1;
+ }
+ warn("overflow in constant expression");
+ return 0;
+}
+
+static bool
 subi(TINT l, TINT r, Type *tp)
 {
         return addi(l, -r, tp);
 }
 
 static bool
+subf(TFLOAT l, TFLOAT r, Type *tp)
+{
+ return addf(l, -r, tp);
+}
+
+static bool
 muli(TINT l, TINT r, Type *tp)
 {
         struct limits *lim = getlimits(tp);
_AT_@ -47,6 +71,24 @@ muli(TINT l, TINT r, Type *tp)
 }
 
 static bool
+mulf(TFLOAT l, TFLOAT r, Type *tp)
+{
+ struct limits *lim = getlimits(tp);
+ TFLOAT max = lim->max.i, min = lim->min.i;
+
+ if (l > -1 && l <= 1 ||
+ r > -1 && r <= 1 ||
+ l < 0 && r < 0 && -l <= max/-r ||
+ l < 0 && r > 0 && l >= min/r ||
+ l > 0 && r < 0 && r >= min/l ||
+ l > 0 && r > 0 && l <= max/r) {
+ return 1;
+ }
+ warn("overflow in constant expression");
+ return 0;
+}
+
+static bool
 divi(TINT l, TINT r, Type *tp)
 {
         struct limits *lim = getlimits(tp);
_AT_@ -63,6 +105,25 @@ divi(TINT l, TINT r, Type *tp)
 }
 
 static bool
+divf(TFLOAT l, TFLOAT r, Type *tp)
+{
+ struct limits *lim = getlimits(tp);
+
+ if (l < 0) l = -l;
+ if (r < 0) r = -r;
+
+ if (r == 0.0) {
+ warn("division by 0");
+ return 0;
+ }
+ if (r < 1.0 && l > lim->max.f * r) {
+ warn("overflow in constant expression");
+ return 0;
+ }
+ return 1;
+}
+
+static bool
 lshi(TINT l, TINT r, Type *tp)
 {
         if (r < 0 || r >= tp->size * 8) {
_AT_@ -174,6 +235,18 @@ foldfloat(int op, Symbol *res, TFLOAT l, TFLOAT r)
 {
         TFLOAT f;
         TINT i;
+ bool (*validate)(TFLOAT, TFLOAT, Type *tp);
+
+ switch (op) {
+ case OADD: validate = addf; break;
+ case OSUB: validate = subf; break;
+ case OMUL: validate = mulf; break;
+ case ODIV: validate = divf; break;
+ default: validate = NULL; break;
+ }
+
+ if (validate && !(*validate)(l, r, res->type))
+ return 0;
 
         switch (op) {
         case OADD: f = l + r; break;
Received on Wed Sep 02 2015 - 12:50:51 CEST

This archive was generated by hypermail 2.3.0 : Wed Sep 02 2015 - 13:00:12 CEST