This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[971031]: Fix for broken hypot funct. on m88k-motorola-sysv3
- To: egcs at cygnus dot com
- Subject: [971031]: Fix for broken hypot funct. on m88k-motorola-sysv3
- From: manfred at s-direktnet dot de
- Date: Wed, 5 Nov 97 14:20:22 +0100
- Cc: egcs-bugs at cygnus dot com
- References: <9711050643.AA07013@lts.sel.alcatel.de>
- Reply-To: manfred at s-direktnet dot de
On Wed, 5 November 1997, 07:43:39, manfred@s-direktnet.de wrote:
These are my results for egcs-971031 on m88k-motorola-sysv3 (aka delta88) using
[snip]
[10]: fixincludes patch for a m88k-motorola-sysv3 from <manfred@s-direktnet.de>
- will send it soon.
[snip]
Here it comes. The problem that's fixed is caused by a stupid
`optimization' in the `hypot' function of Motorola's libm.a.
DESCRIPTION
hypot(x,y) returns
sqrt(x*x + y*y)
If either x or y is 0, hypot simply returns the other value regardless
of any sign. This, of course, causes pretty much failures during the
libstdc++ tests, because the lib itself uses hypot frequently.
hypot (0.0, -1.0) e.g. returns -1.0, not 1.0 as one would
expect. Since I cannot fix the library (nor can I request a fixed one
from Motorola because my customers insist on the particular OS version
we're using here), I provide a `fake_hypot' function in the fixed
`math.h' file which takes care of this bug:
#ifdef __STDC__
static __inline__ double fake_hypot (double x, double y)
#else
static __inline__ double fake_hypot (x, y)
double x, y;
#endif
{
return fabs (hypot (x, y));
}
#define hypot fake_hypot
Another fix is for the strlen, etc. functions, which are defined
differently depending on _POSIX_SOURCE; fixincludes fails to fix this
one.
Wed Nov 5 13:31:40 1997 Manfred Hollstein <manfred@s-direktnet.de>
* fixincludes (str{len,spn,cspn} return value): Handle different
layout on sysV88.
(hypot): Provide a fake for hypot which is broken on m88k-motorola-sysv3.
diff --context --recursive --show-c-function -x *.o -x *.info* -x *.html* -x *.elc -x *.dvi -x *.orig -x *~ -x version.el egcs-971031.orig/gcc/fixincludes egcs-971031/gcc/fixincludes
*** egcs-971031.orig/gcc/fixincludes Tue Sep 2 20:38:30 1997
- --- egcs-971031/gcc/fixincludes Mon Nov 3 12:44:33 1997
*************** INPUT=${2-${INPUT-/usr/include}}
*** 12,17 ****
- --- 12,25 ----
# Directory in which to store the results.
LIB=${1?"fixincludes: output directory not specified"}
+ # Define what target system we're fixing.
+ if test -r ./Makefile; then
+ target_canonical="`sed -n -e 's,^target[ ]*=[ ]*\(.*\)$,\1,p' < Makefile`"
+ test -z "${target_canonical}" && target_canonical=unknown
+ else
+ target_canonical=unknown
+ fi
+
# Define PWDCMD as a command to use to get the working dir
# in the form that we want.
PWDCMD=pwd
*************** fi
*** 1982,1987 ****
- --- 1990,1996 ----
# Correct the return type for strlen in string.h on Lynx.
# Correct the argument type for ffs in string.h on Alpha OSF/1 V2.0.
# Add missing const for strdup on OSF/1 V3.0.
+ # On sysV88 layout is slightly different.
file=string.h
if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
*************** if [ -r ${LIB}/$file ]; then
*** 2000,2005 ****
- --- 2009,2016 ----
-e 's/^\( strncmp()\),\n\( strlen(),\)$/\1;\
extern unsigned int\
\2/'\
+ -e '/^extern int$/N'\
+ -e 's/^extern int\(\n strlen(),\)/extern size_t\1/' \
${LIB}/$file > ${LIB}/${file}.sed
rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
if cmp $file ${LIB}/$file >/dev/null 2>&1; then
*************** do
*** 2284,2289 ****
- --- 2295,2335 ----
fi
fi
done
+
+ # libm.a on m88k-motorola-sysv3 contains a stupid optimization for function
+ # hypot(), which returns the second argument without even looking at its value
+ # if the other is 0.0
+ file=math.h
+ if [ $target_canonical = m88k-motorola-sysv3 ]; then
+ if [ -r $file ] && [ ! -r ${LIB}/$file ]; then
+ cp $file ${LIB}/$file >/dev/null 2>&1 || echo "Can't copy $file"
+ chmod +w ${LIB}/$file 2>/dev/null
+ chmod a+r ${LIB}/$file 2>/dev/null
+ fi
+
+ if [ -r ${LIB}/$file ]; then
+ echo Fixing $file, hypot definition
+ sed -e '/^extern double hypot();$/a\
+ \/* Workaround a stupid Motorola optimization if one\
+ of x or y is 0.0 and the other is negative! *\/\
+ #ifdef __STDC__\
+ static __inline__ double fake_hypot (double x, double y)\
+ #else\
+ static __inline__ double fake_hypot (x, y)\
+ double x, y;\
+ #endif\
+ {\
+ return fabs (hypot (x, y));\
+ }\
+ #define hypot fake_hypot
+ ' \
+ ${LIB}/$file > ${LIB}/${file}.sed
+ rm -f ${LIB}/$file; mv ${LIB}/${file}.sed ${LIB}/$file
+ if cmp $file ${LIB}/$file >/dev/null 2>&1; then
+ rm -f ${LIB}/$file
+ fi
+ fi
+ fi
# math.h on SunOS 4 puts the declaration of matherr before the definition
# of struct exception, so the prototype (added by fixproto) causes havoc.