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;
signature.asc
Description: Digital signature

