tags 634257 + patch
thanks

I found one more place with bus error, it is in function valFloat__LD(),
also unaligned access to double variable.

It seems the problem is that GCC optimizes code like this:

  union
  { double d;
    fword  l;
  } val;

  val.l = *v;

  return val.d

to just this:

  return *(double *)v;

Given that this abuse of unions has undefined behavior according to C
standard, I cannot blame GCC for this. In the attached patch I replaces
type punning by using memcpy. That should work on all architectures. I
tested it in qemu and there is no bus error anymore, but I did not try
to finish the compilation - it is veeeeery slow. It also seems to work
fine on x86_64.

Regards,
Eugeniy Meshcheryakov
Description: Fix FTBFS on mipsel

Using type punning via unions combined with optimizations causes
unaligned memory access on mipsel. The patch replaces uses of unious by
calls to memcpy().

--- swi-prolog-5.10.4.orig/src/pl-alloc.c
+++ swi-prolog-5.10.4/src/pl-alloc.c
@@ -1041,15 +1041,9 @@ doublecpy(void *to, void *from)
 
 double					/* take care of alignment! */
 valFloat__LD(word w ARG_LD)
-{ fword *v = (fword *)valIndirectP(w);
-  union
-  { double d;
-    fword  l;
-  } val;
-
-  val.l = *v;
-
-  return val.d;
+{ double d;
+  memcpy(&d, valIndirectP(w), sizeof(d));
+  return d;
 }
 
 
@@ -1057,11 +1051,6 @@ int
 put_double(Word at, double d, int flags ARG_LD)
 { Word p;
   word m = mkIndHdr(WORDS_PER_DOUBLE, TAG_FLOAT);
-  union
-  { double d;
-    fword  l;
-  } val;
-  fword *v;
 
   if ( flags != ALLOW_CHECKED && !hasGlobalSpace(2+WORDS_PER_DOUBLE) )
   { int rc = ensureGlobalSpace(2+WORDS_PER_DOUBLE, flags);
@@ -1074,11 +1063,9 @@ put_double(Word at, double d, int flags
 
   *at = consPtr(p, TAG_FLOAT|STG_GLOBAL);
 
-  val.d = d;
   *p++ = m;
-  v = (fword *)p;
-  *v++ = val.l;
-  p = (Word) v;
+  memcpy(p, &d, sizeof(d));
+  p += WORDS_PER_DOUBLE;
   *p = m;
 
   return TRUE;

Attachment: signature.asc
Description: Digital signature

Reply via email to