shithub: femtolisp

Download patch

ref: 08787a01cdd4103d1e5efa34b661b524651ec538
parent: ecfd81148fe6a4d77924b8201051fadc36c3e42b
author: JeffBezanson <jeff.bezanson@gmail.com>
date: Tue Jul 28 22:32:23 EDT 2009

fixing use of an undefined behavior that was breaking compiles occasionally


--- a/femtolisp/Makefile
+++ b/femtolisp/Makefile
@@ -12,7 +12,7 @@
 LIBS = $(LLT) -lm
 
 DEBUGFLAGS = -g -DDEBUG $(FLAGS)
-SHIPFLAGS = -O2 -DNDEBUG -march=native $(FLAGS)
+SHIPFLAGS = -O3 -DNDEBUG $(FLAGS)
 
 default: release test
 
--- a/femtolisp/equal.c
+++ b/femtolisp/equal.c
@@ -281,7 +281,10 @@
 static uptrint_t bounded_hash(value_t a, int bound, int *oob)
 {
     *oob = 0;
-    double d;
+    union {
+        double d;
+        int64_t i64;
+    } u;
     numerictype_t nt;
     size_t i, len;
     cvalue_t *cv;
@@ -292,8 +295,8 @@
     switch(tg) {
     case TAG_NUM :
     case TAG_NUM1:
-        d = numval(a);
-        return doublehash(*(int64_t*)&d);
+        u.d = (double)numval(a);
+        return doublehash(u.i64);
     case TAG_FUNCTION:
         if (uintval(a) > N_BUILTINS)
             return bounded_hash(((function_t*)ptr(a))->bcode, bound, oob);
@@ -304,8 +307,8 @@
         cp = (cprim_t*)ptr(a);
         data = cp_data(cp);
         nt = cp_numtype(cp);
-        d = conv_to_double(data, nt);
-        return doublehash(*(int64_t*)&d);
+        u.d = conv_to_double(data, nt);
+        return doublehash(u.i64);
     case TAG_CVALUE:
         cv = (cvalue_t*)ptr(a);
         data = cv_data(cv);
--- a/llt/fp.c
+++ b/llt/fp.c
@@ -52,12 +52,14 @@
 
 int dbl_equals(double a, double b)
 {
+    union { double d; int64_t i; } ua;
+    union { double d; int64_t i; } ub;
     int64_t aint, bint;
 
     if (a == b)
         return 1;
-    aint = *(int64_t*)&a;
-    bint = *(int64_t*)&b;
+    ua.d = a; aint = ua.i;
+    ub.d = b; bint = ub.i;
     if (aint < 0)
         aint = BIT63 - aint;
     if (bint < 0)
@@ -72,12 +74,14 @@
 
 int flt_equals(float a, float b)
 {
+    union { float f; int32_t i; } ua;
+    union { float f; int32_t i; } ub;
     int32_t aint, bint;
 
     if (a == b)
         return 1;
-    aint = *(int32_t*)&a;
-    bint = *(int32_t*)&b;
+    ua.f = a; aint = ua.i;
+    ub.f = b; bint = ub.i;
     if (aint < 0)
         aint = BIT31 - aint;
     if (bint < 0)