summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libguile/ChangeLog7
-rw-r--r--libguile/inline.h20
-rw-r--r--libguile/num2float.i.c8
-rw-r--r--libguile/numbers.c11
4 files changed, 31 insertions, 15 deletions
diff --git a/libguile/ChangeLog b/libguile/ChangeLog
index fb7da086c..13ac529d0 100644
--- a/libguile/ChangeLog
+++ b/libguile/ChangeLog
@@ -1,3 +1,10 @@
+2002-09-24 Gary Houston <ghouston@arglist.com>
+
+ * inline.h (scm_double_cell): prevent reordering of statements
+ with any following code (for GCC 3 strict-aliasing).
+ * numbers.c (scm_make_real), num2float.i.c (FLOAT2NUM): removed
+ the earlier version of the reordering prevention.
+
2002-09-19 Han-Wen Nienhuys <hanwen@cs.uu.nl>
* inline.h (scm_double_cell): move SET_GCMARK set out of if body.
diff --git a/libguile/inline.h b/libguile/inline.h
index d4cd67606..393182b6a 100644
--- a/libguile/inline.h
+++ b/libguile/inline.h
@@ -215,6 +215,26 @@ scm_double_cell (scm_t_bits car, scm_t_bits cbr,
#endif
+ /* When this function is inlined, it's possible that the last
+ SCM_GC_SET_CELL_WORD above will be adjacent to a following
+ initialization of z. E.g., it occurred in scm_make_real. GCC
+ from around version 3 (e.g., certainly 3.2) began taking
+ advantage of strict C aliasing rules which say that it's OK to
+ interchange the initialization above and the one below when the
+ pointer types appear to differ sufficiently. We don't want that,
+ of course. GCC allows this behaviour to be disabled with the
+ -fno-strict-aliasing option, but would also need to be supplied
+ by Guile users. Instead, the following statements prevent the
+ reordering.
+ */
+#ifdef __GNUC__
+ asm volatile ("" : : : "memory");
+#else
+ /* portable version, just in case any other compiler does the same
+ thing. */
+ scm_remember_upto_here_1 (z);
+#endif
+
return z;
}
diff --git a/libguile/num2float.i.c b/libguile/num2float.i.c
index 5fd9180c7..08687a875 100644
--- a/libguile/num2float.i.c
+++ b/libguile/num2float.i.c
@@ -31,12 +31,8 @@ NUM2FLOAT (SCM num, unsigned long int pos, const char *s_caller)
SCM
FLOAT2NUM (FTYPE n)
{
- SCM z;
- z = scm_double_cell (scm_tc16_real, 0, 0, 0);
- /*
- See scm_make_real().
- */
- scm_remember_upto_here_1 (z);
+ SCM z = scm_double_cell (scm_tc16_real, 0, 0, 0);
+
SCM_REAL_VALUE (z) = n;
return z;
}
diff --git a/libguile/numbers.c b/libguile/numbers.c
index 8393c62ca..bb01d7ad3 100644
--- a/libguile/numbers.c
+++ b/libguile/numbers.c
@@ -3013,15 +3013,8 @@ SCM_DEFINE (scm_string_to_number, "string->number", 1, 1, 0,
SCM
scm_make_real (double x)
{
- SCM z;
- z = scm_double_cell (scm_tc16_real, 0, 0, 0);
-
- /*
- scm_double_cell is inlined. strict C aliasing rules say that it's
- OK to interchange the initialization above and the one below. We
- don't want that, of course.
- */
- scm_remember_upto_here_1 (z);
+ SCM z = scm_double_cell (scm_tc16_real, 0, 0, 0);
+
SCM_REAL_VALUE (z) = x;
return z;
}