Blame invalid.c

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