Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2008-06-25 05:45:02 +0400
committerHans-Peter Nilsson <hp@axis.com>2008-06-25 05:45:02 +0400
commit5592f939b4762cf0eda460d502f880baa179e201 (patch)
tree7ca59247975079e18eee83310a288e635639b886 /newlib/libc/stdlib/mprec.h
parent7b3e3bfd49bef27c5df703e9c079c0c1eb454ecc (diff)
Fix strict-aliasing issues with _strtod_r and Storeinc.
* libc/stdlib/strtod.c (_strtod_r): Change local variables aadj, rv, rv0 from double to type U. Use accessor macros dval, dword0 and dword1 for all accesses except for the ULtod call, where rv.i replaces the pointer cast. * libc/stdlib/mprec.h (U): Rename member L to i for easier re-use of access macros. Tweak comment. Remove #ifdef'd YES_ALIAS code. (dword0, dword1, dval): Define in terms of uncast union member access. Ditto for _DOUBLE_IS_32BITS variants. (Storeinc): Replace aliasing-flawed microoptimized definition with alternative suggested in comment. Remove now stale comment.
Diffstat (limited to 'newlib/libc/stdlib/mprec.h')
-rw-r--r--newlib/libc/stdlib/mprec.h49
1 files changed, 11 insertions, 38 deletions
diff --git a/newlib/libc/stdlib/mprec.h b/newlib/libc/stdlib/mprec.h
index 498de5b74..dea89bf11 100644
--- a/newlib/libc/stdlib/mprec.h
+++ b/newlib/libc/stdlib/mprec.h
@@ -78,31 +78,18 @@ union double_union
#define word1(x) (x.i[1])
#endif
-
-/* The following is taken from gdtoaimp.h for use with new strtod. */
+/* The following is taken from gdtoaimp.h for use with new strtod, but
+ adjusted to avoid invalid type-punning. */
typedef __int32_t Long;
-typedef union { double d; __ULong L[2]; } U;
-#ifdef YES_ALIAS
-#define dval(x) x
-#ifdef IEEE_8087
-#define dword0(x) ((__ULong *)&x)[1]
-#define dword1(x) ((__ULong *)&x)[0]
-#else
-#define dword0(x) ((__ULong *)&x)[0]
-#define dword1(x) ((__ULong *)&x)[1]
-#endif
-#else /* !YES_ALIAS */
-#ifdef IEEE_8087
-#define dword0(x) ((U*)&x)->L[1]
-#define dword1(x) ((U*)&x)->L[0]
-#else
-#define dword0(x) ((U*)&x)->L[0]
-#define dword1(x) ((U*)&x)->L[1]
-#endif
-#define dval(x) ((U*)&x)->d
-#endif /* YES_ALIAS */
+/* Unfortunately, because __ULong might be a different type than
+ __uint32_t, we can't re-use union double_union as-is without
+ further edits in strtod.c. */
+typedef union { double d; __ULong i[2]; } U;
+#define dword0(x) word0(x)
+#define dword1(x) word1(x)
+#define dval(x) (x.d)
#undef SI
#ifdef Sudden_Underflow
@@ -111,17 +98,7 @@ typedef union { double d; __ULong L[2]; } U;
#define SI 0
#endif
-/* The following definition of Storeinc is appropriate for MIPS processors.
- * An alternative that might be better on some machines is
- * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
- */
-#if defined (__IEEE_BYTES_LITTLE_ENDIAN) + defined (IEEE_8087) + defined (VAX)
-#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
-((unsigned short *)a)[0] = (unsigned short)c, a++)
-#else
-#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
-((unsigned short *)a)[1] = (unsigned short)c, a++)
-#endif
+#define Storeinc(a,b,c) (*(a)++ = (b) << 16 | (c) & 0xffff)
/* #define P DBL_MANT_DIG */
/* Ten_pmax = floor(P*log(2)/log(5)) */
@@ -167,11 +144,7 @@ typedef union { double d; __ULong L[2]; } U;
#define word0(x) (x.i[0])
#define word1(x) 0
-#ifdef YES_ALIAS
-#define dword0(x) ((__ULong *)&x)[0]
-#else
-#define dword0(x) ((U*)&x)->L[0]
-#endif
+#define dword0(x) word0(x)
#define dword1(x) 0
#else