]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Make division by zero signal SIGFPE on all platforms.
authorBruno Haible <bruno@clisp.org>
Fri, 7 Jun 2002 12:41:14 +0000 (12:41 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:08:35 +0000 (12:08 +0200)
intl/ChangeLog
intl/dcigettext.c
intl/eval-plural.h
m4/ChangeLog
m4/Makefile.am
m4/gettext.m4
m4/intdiv0.m4 [new file with mode: 0644]
src/ChangeLog
src/msgfmt.c

index 35ff7f8a8782dfabd6ce2ad8b367dffad7cd52ec..2e18e90d5d3bbebe03a37c8ed2b97dd16fe03ba3 100644 (file)
@@ -1,3 +1,10 @@
+2002-06-07  Bruno Haible  <bruno@clisp.org>
+
+       * dcigettext.c (INTDIV0_RAISES_SIGFPE): Define a fallback.
+       Include <signal.h>.
+       * eval-plural.h (plural_eval): Let division by zero cause SIGFPE on
+       all platforms.
+
 2002-05-30  Bruno Haible  <bruno@clisp.org>
 
        * libgnuintl.h (_INTL_REDIRECT_ASM, _INTL_REDIRECT_INLINE,
index 329dc0985a69e4e5c8fee8c0f7ca0372e820a1e0..b5bf3fb5dc1b2bd354c68c4555d5c4162a182ec9 100644 (file)
@@ -64,6 +64,20 @@ extern int errno;
 
 #include <locale.h>
 
+#ifdef _LIBC
+  /* Guess whether integer division by zero raises signal SIGFPE.
+     Set to 1 only if you know for sure.  In case of doubt, set to 0.  */
+# if defined __alpha__ || defined __arm__ || defined __i386__ \
+     || defined __m68k__ || defined __s390__
+#  define INTDIV0_RAISES_SIGFPE 1
+# else
+#  define INTDIV0_RAISES_SIGFPE 0
+# endif
+#endif
+#if !INTDIV0_RAISES_SIGFPE
+# include <signal.h>
+#endif
+
 #if defined HAVE_SYS_PARAM_H || defined _LIBC
 # include <sys/param.h>
 #endif
index 44f493425e93d47c8dc036c272c9e02ef70020a6..19c7ca6aee34c79295dab941b0471acaf64d254e 100644 (file)
@@ -68,8 +68,16 @@ plural_eval (pexp, n)
              case mult:
                return leftarg * rightarg;
              case divide:
+#if !INTDIV0_RAISES_SIGFPE
+               if (rightarg == 0)
+                 raise (SIGFPE);
+#endif
                return leftarg / rightarg;
              case module:
+#if !INTDIV0_RAISES_SIGFPE
+               if (rightarg == 0)
+                 raise (SIGFPE);
+#endif
                return leftarg % rightarg;
              case plus:
                return leftarg + rightarg;
index 8fec47a8ecba63cc427466375c307c1eacb874f7..9a40fd506d25fa02d79252ad65ee077ffdbc837f 100644 (file)
@@ -1,3 +1,10 @@
+2002-06-07  Bruno Haible  <bruno@clisp.org>
+
+       * intdiv0.m4: New file.
+       * gettext.m4 (AM_INTL_SUBDIR): Require gt_INTDIV0.
+       * Makefile.am (aclocal_DATA): Add intdiv0.m4.
+       (EXTRA_DIST): Add intdiv0.m4.
+
 2002-05-18  Bruno Haible  <bruno@clisp.org>
 
        Make it possible to invoke AM_ICONV after AM_GNU_GETTEXT.
index 58d06f4245e7d4f2cde86e059b3c68934ed84d5e..7ebe8b8ce4612a3be9da2eac808433dd1db6c7f4 100644 (file)
@@ -1,15 +1,16 @@
 ## Process this file with automake to produce Makefile.in -*-Makefile-*-
 
 aclocaldir = @aclocaldir@
-aclocal_DATA = codeset.m4 gettext.m4 glibc21.m4 iconv.m4 isc-posix.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 lcmessage.m4 progtest.m4
+aclocal_DATA = codeset.m4 gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 isc-posix.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 lcmessage.m4 progtest.m4
 
 # Generate this list with
 # find . -type f -name '*.m4' -printf '%f\n'|sort |fmt |tr '\012' @ \
 #   |sed 's/@$/%/;s/@/ \\@/g' |tr @% '\012\012'
 EXTRA_DIST = README \
 backupfile.m4 c-bs-a.m4 codeset.m4 error.m4 flex.m4 fnmatch.m4 getline.m4 \
-gettext.m4 glibc21.m4 hostname.m4 iconv.m4 inttypes_h.m4 isc-posix.m4 \
-javacomp.m4 javaexec.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 \
-libtool.m4 mbrtowc.m4 mbstate_t.m4 mbswidth.m4 mkdtemp.m4 progtest.m4 \
-setenv.m4 setlocale.m4 siginfo.m4 signalblocking.m4 signed.m4 ssize_t.m4 \
-stdbool.m4 stdint_h.m4 tmpdir.m4 uintmax_t.m4 ulonglong.m4 unionwait.m4
+gettext.m4 glibc21.m4 hostname.m4 iconv.m4 intdiv0.m4 inttypes_h.m4 \
+isc-posix.m4 javacomp.m4 javaexec.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 \
+lib-prefix.m4 libtool.m4 mbrtowc.m4 mbstate_t.m4 mbswidth.m4 mkdtemp.m4 \
+progtest.m4 setenv.m4 setlocale.m4 siginfo.m4 signalblocking.m4 signed.m4 \
+ssize_t.m4 stdbool.m4 stdint_h.m4 tmpdir.m4 uintmax_t.m4 ulonglong.m4 \
+unionwait.m4
index a65b03d4662a1c428d566d903da89e713e2da4d4..146cef2f8547d705fffb9e1702ee7dfb27107959 100644 (file)
@@ -494,6 +494,7 @@ AC_DEFUN([AM_INTL_SUBDIR],
   AC_REQUIRE([AC_FUNC_ALLOCA])dnl
   AC_REQUIRE([AC_FUNC_MMAP])dnl
   AC_REQUIRE([jm_GLIBC21])dnl
+  AC_REQUIRE([gt_INTDIV0])dnl
 
   AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h stddef.h \
 stdlib.h string.h unistd.h sys/param.h])
diff --git a/m4/intdiv0.m4 b/m4/intdiv0.m4
new file mode 100644 (file)
index 0000000..55dddcf
--- /dev/null
@@ -0,0 +1,72 @@
+# intdiv0.m4 serial 1 (gettext-0.11.3)
+dnl Copyright (C) 2002 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License.  As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that contains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([gt_INTDIV0],
+[
+  AC_REQUIRE([AC_PROG_CC])dnl
+  AC_REQUIRE([AC_CANONICAL_HOST])dnl
+
+  AC_CACHE_CHECK([whether integer division by zero raises SIGFPE],
+    gt_cv_int_divbyzero_sigfpe,
+    [
+      AC_TRY_RUN([
+#include <stdlib.h>
+#include <signal.h>
+
+static void
+#ifdef __cplusplus
+sigfpe_handler (int sig)
+#else
+sigfpe_handler (sig) int sig;
+#endif
+{
+  /* Exit with code 0 if SIGFPE, with code 1 if any other signal.  */
+  exit (sig != SIGFPE);
+}
+
+int x = 1;
+int y = 0;
+int z;
+int nan;
+
+int main ()
+{
+  signal (SIGFPE, sigfpe_handler);
+/* IRIX and AIX (when "xlc -qcheck" is used) yield signal SIGTRAP.  */
+#if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP)
+  signal (SIGTRAP, sigfpe_handler);
+#endif
+/* Linux/SPARC yields signal SIGILL.  */
+#if defined (__sparc__) && defined (__linux__)
+  signal (SIGILL, sigfpe_handler);
+#endif
+
+  z = x / y;
+  nan = y / y;
+  exit (1);
+}
+], gt_cv_int_divbyzero_sigfpe=yes, gt_cv_int_divbyzero_sigfpe=no,
+        [
+          # Guess based on the CPU.
+          case "$host_cpu" in
+            alpha* | i[34567]86 | m68k | s390*)
+              gt_cv_int_divbyzero_sigfpe="guessing yes";;
+            *)
+              gt_cv_int_divbyzero_sigfpe="guessing no";;
+          esac
+        ])
+    ])
+  case "$gt_cv_int_divbyzero_sigfpe" in
+    *yes) value=1;;
+    *) value=0;;
+  esac
+  AC_DEFINE_UNQUOTED(INTDIV0_RAISES_SIGFPE, $value,
+    [Define if integer division by zero raises signal SIGFPE.])
+])
index 3f9355d5eb59ef830bc8ed2b1157727fd9e2b8a8..6a95a356e4bb8c98f539462002e232b252f2ac67 100644 (file)
@@ -1,3 +1,9 @@
+2002-06-07  Bruno Haible  <bruno@clisp.org>
+
+       * msgfmt.c (install_sigfpe_handler): Assume the signal is always
+       SIGFPE, regardless of the platform.
+       (uninstall_sigfpe_handler): Likewise.
+
 2002-05-29  Bruno Haible  <bruno@clisp.org>
 
        * dir-list.h (dir_list_save_reset, dir_list_restore): New declarations.
index f8883f94e04dacf654e06f26604d1cae26147227..058178d27e64dbd0d6088f964c0c9abd2f2d08a1 100644 (file)
@@ -720,10 +720,6 @@ install_sigfpe_handler ()
   sigaction (SIGFPE, &action, (struct sigaction *) NULL);
 #else
   signal (SIGFPE, sigfpe_handler);
-  /* Irix and AIX send SIGTRAP, not SIGFPE.  */
-# if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP)
-  signal (SIGTRAP, sigfpe_handler);
-# endif
 #endif
 }
 
@@ -738,10 +734,6 @@ uninstall_sigfpe_handler ()
   sigaction (SIGFPE, &action, (struct sigaction *) NULL);
 #else
   signal (SIGFPE, SIG_DFL);
-  /* Irix and AIX send SIGTRAP, not SIGFPE.  */
-# if (defined (__sgi) || defined (_AIX)) && defined (SIGTRAP)
-  signal (SIGTRAP, SIG_DFL);
-# endif
 #endif
 }