Blame invalid.c

Packit 15dc08
/* __gmp_invalid_operation -- invalid floating point operation.
Packit 15dc08
Packit 15dc08
   THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY.  THEY'RE ALMOST
Packit 15dc08
   CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
Packit 15dc08
   FUTURE GNU MP RELEASES.
Packit 15dc08
Packit 15dc08
Copyright 2003 Free Software Foundation, Inc.
Packit 15dc08
Packit 15dc08
This file is part of the GNU MP Library.
Packit 15dc08
Packit 15dc08
The GNU MP Library is free software; you can redistribute it and/or modify
Packit 15dc08
it under the terms of either:
Packit 15dc08
Packit 15dc08
  * the GNU Lesser General Public License as published by the Free
Packit 15dc08
    Software Foundation; either version 3 of the License, or (at your
Packit 15dc08
    option) any later version.
Packit 15dc08
Packit 15dc08
or
Packit 15dc08
Packit 15dc08
  * the GNU General Public License as published by the Free Software
Packit 15dc08
    Foundation; either version 2 of the License, or (at your option) any
Packit 15dc08
    later version.
Packit 15dc08
Packit 15dc08
or both in parallel, as here.
Packit 15dc08
Packit 15dc08
The GNU MP Library is distributed in the hope that it will be useful, but
Packit 15dc08
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit 15dc08
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
Packit 15dc08
for more details.
Packit 15dc08
Packit 15dc08
You should have received copies of the GNU General Public License and the
Packit 15dc08
GNU Lesser General Public License along with the GNU MP Library.  If not,
Packit 15dc08
see https://www.gnu.org/licenses/.  */
Packit 15dc08
Packit 15dc08
#include "config.h"
Packit 15dc08
Packit 15dc08
#include <signal.h>
Packit 15dc08
#include <stdlib.h>
Packit 15dc08
Packit 15dc08
#if HAVE_UNISTD_H
Packit 15dc08
#include <unistd.h>  /* for getpid */
Packit 15dc08
#endif
Packit 15dc08
Packit 15dc08
#include "gmp.h"
Packit 15dc08
#include "gmp-impl.h"
Packit 15dc08
Packit 15dc08
Packit 15dc08
/* Incidentally, kill is not available on mingw, but that's ok, it has raise
Packit 15dc08
   and we'll be using that.  */
Packit 15dc08
#if ! HAVE_RAISE
Packit 15dc08
#define raise(sig)   kill (getpid(), sig)
Packit 15dc08
#endif
Packit 15dc08
Packit 15dc08
Packit 15dc08
/* __gmp_invalid_operation is for an invalid floating point operation, like
Packit 15dc08
   mpz_set_d on a NaN or Inf.  It's done as a subroutine to minimize code in
Packit 15dc08
   places raising an exception.
Packit 15dc08
Packit 15dc08
   feraiseexcept(FE_INVALID) is not used here, since unfortunately on most
Packit 15dc08
   systems it would require libm.
Packit 15dc08
Packit 15dc08
   Alternatives:
Packit 15dc08
Packit 15dc08
   It might be possible to check whether a hardware "invalid operation" trap
Packit 15dc08
   is enabled or not before raising a signal.  This would require all
Packit 15dc08
   callers to be prepared to continue with some bogus result.  Bogus returns
Packit 15dc08
   are bad, but presumably an application disabling the trap is prepared for
Packit 15dc08
   that.
Packit 15dc08
Packit 15dc08
   On some systems (eg. BSD) the signal handler can find out the reason for
Packit 15dc08
   a SIGFPE (overflow, invalid, div-by-zero, etc).  Perhaps we could get
Packit 15dc08
   that into our raise too.
Packit 15dc08
Packit 15dc08
   i386 GLIBC implements feraiseexcept(FE_INVALID) with an asm fdiv 0/0.
Packit 15dc08
   That would both respect the exceptions mask and give a reason code in a
Packit 15dc08
   BSD signal.  */
Packit 15dc08
Packit 15dc08
void
Packit 15dc08
__gmp_invalid_operation (void)
Packit 15dc08
{
Packit 15dc08
  raise (SIGFPE);
Packit 15dc08
  abort ();
Packit 15dc08
}