mirror of
https://github.com/python/cpython.git
synced 2025-10-10 00:43:41 +00:00
Changes for Lee Busby's SIGFPE patch set.
Two new modules fpectl and fpetest. Surround various and sundry f.p. operations with PyFPE_*_PROTECT macros.
This commit is contained in:
parent
0ae748d3c4
commit
52fa3a6909
8 changed files with 492 additions and 1 deletions
|
@ -724,10 +724,14 @@ Tkapp_ExprDouble (self, args)
|
||||||
{
|
{
|
||||||
char *s;
|
char *s;
|
||||||
double v;
|
double v;
|
||||||
|
int retval;
|
||||||
|
|
||||||
if (!PyArg_Parse(args, "s", &s))
|
if (!PyArg_Parse(args, "s", &s))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (Tcl_ExprDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
|
PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0)
|
||||||
|
retval = Tcl_ExprDouble (Tkapp_Interp (self), s, &v);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
|
if (retval == TCL_ERROR)
|
||||||
return Tkinter_Error(self);
|
return Tkinter_Error(self);
|
||||||
return Py_BuildValue("d", v);
|
return Py_BuildValue("d", v);
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,7 +247,9 @@ math_1(args, func)
|
||||||
if (!PyArg_ParseTuple(args, "D", &x))
|
if (!PyArg_ParseTuple(args, "D", &x))
|
||||||
return NULL;
|
return NULL;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
PyFPE_START_PROTECT("complex function", return 0)
|
||||||
x = (*func)(x);
|
x = (*func)(x);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
CHECK(x.real);
|
CHECK(x.real);
|
||||||
CHECK(x.imag);
|
CHECK(x.imag);
|
||||||
if (errno != 0)
|
if (errno != 0)
|
||||||
|
|
244
Modules/fpectlmodule.c
Normal file
244
Modules/fpectlmodule.c
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
/ Copyright (c) 1996. \
|
||||||
|
| The Regents of the University of California. |
|
||||||
|
| All rights reserved. |
|
||||||
|
| |
|
||||||
|
| Permission to use, copy, modify, and distribute this software for |
|
||||||
|
| any purpose without fee is hereby granted, provided that this en- |
|
||||||
|
| tire notice is included in all copies of any software which is or |
|
||||||
|
| includes a copy or modification of this software and in all |
|
||||||
|
| copies of the supporting documentation for such software. |
|
||||||
|
| |
|
||||||
|
| This work was produced at the University of California, Lawrence |
|
||||||
|
| Livermore National Laboratory under contract no. W-7405-ENG-48 |
|
||||||
|
| between the U.S. Department of Energy and The Regents of the |
|
||||||
|
| University of California for the operation of UC LLNL. |
|
||||||
|
| |
|
||||||
|
| DISCLAIMER |
|
||||||
|
| |
|
||||||
|
| This software was prepared as an account of work sponsored by an |
|
||||||
|
| agency of the United States Government. Neither the United States |
|
||||||
|
| Government nor the University of California nor any of their em- |
|
||||||
|
| ployees, makes any warranty, express or implied, or assumes any |
|
||||||
|
| liability or responsibility for the accuracy, completeness, or |
|
||||||
|
| usefulness of any information, apparatus, product, or process |
|
||||||
|
| disclosed, or represents that its use would not infringe |
|
||||||
|
| privately-owned rights. Reference herein to any specific commer- |
|
||||||
|
| cial products, process, or service by trade name, trademark, |
|
||||||
|
| manufacturer, or otherwise, does not necessarily constitute or |
|
||||||
|
| imply its endorsement, recommendation, or favoring by the United |
|
||||||
|
| States Government or the University of California. The views and |
|
||||||
|
| opinions of authors expressed herein do not necessarily state or |
|
||||||
|
| reflect those of the United States Government or the University |
|
||||||
|
| of California, and shall not be used for advertising or product |
|
||||||
|
\ endorsement purposes. /
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Floating point exception control module.
|
||||||
|
|
||||||
|
This Python module provides bare-bones control over floating point
|
||||||
|
units from several hardware manufacturers. Specifically, it allows
|
||||||
|
the user to turn on the generation of SIGFPE whenever any of the
|
||||||
|
three serious IEEE 754 exceptions (Division by Zero, Overflow,
|
||||||
|
Invalid Operation) occurs. We currently ignore Underflow and
|
||||||
|
Inexact Result exceptions, although those could certainly be added
|
||||||
|
if desired.
|
||||||
|
|
||||||
|
The module also establishes a signal handler for SIGFPE during
|
||||||
|
initialization. This builds on code found in the Python
|
||||||
|
distribution at Include/pyfpe.h and Python/pyfpe.c. If those files
|
||||||
|
are not in your Python distribution, find them in a patch at
|
||||||
|
ftp://icf.llnl.gov/pub/python/busby/patches.961108.tgz.
|
||||||
|
|
||||||
|
This module is only useful to you if it happens to include code
|
||||||
|
specific for your hardware and software environment. If you can
|
||||||
|
contribute OS-specific code for new platforms, or corrections for
|
||||||
|
the code provided, it will be greatly appreciated.
|
||||||
|
|
||||||
|
** Version 1.0: September 20, 1996. Lee Busby, LLNL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "Python.h"
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#ifndef WANT_SIGFPE_HANDLER
|
||||||
|
/* Define locally if they are not defined in Python. This gives only
|
||||||
|
* the limited control to induce a core dump in case of an exception.
|
||||||
|
*/
|
||||||
|
static jmp_buf PyFPE_jbuf;
|
||||||
|
static int PyFPE_counter = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef RETSIGTYPE Sigfunc(int);
|
||||||
|
static Sigfunc sigfpe_handler;
|
||||||
|
static void fpe_reset(Sigfunc *);
|
||||||
|
|
||||||
|
static PyObject *fpe_error;
|
||||||
|
void initfpectl(void);
|
||||||
|
static PyObject *turnon_sigfpe (PyObject *self,PyObject *args);
|
||||||
|
static PyObject *turnoff_sigfpe (PyObject *self,PyObject *args);
|
||||||
|
|
||||||
|
static PyMethodDef fpectl_methods[] = {
|
||||||
|
{"turnon_sigfpe", (PyCFunction) turnon_sigfpe, 1},
|
||||||
|
{"turnoff_sigfpe", (PyCFunction) turnoff_sigfpe, 1},
|
||||||
|
{0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyObject *turnon_sigfpe(PyObject *self,PyObject *args)
|
||||||
|
{
|
||||||
|
/* Do any architecture-specific one-time only initialization here. */
|
||||||
|
|
||||||
|
fpe_reset(sigfpe_handler);
|
||||||
|
Py_INCREF (Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fpe_reset(Sigfunc *handler)
|
||||||
|
{
|
||||||
|
/* Reset the exception handling machinery, and reset the signal
|
||||||
|
* handler for SIGFPE to the given handler.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-- IRIX -----------------------------------------------------------------*/
|
||||||
|
#if defined(sgi)
|
||||||
|
/* See man page on handle_sigfpes -- must link with -lfpe
|
||||||
|
* My usage doesn't follow the man page exactly. Maybe somebody
|
||||||
|
* else can explain handle_sigfpes to me....
|
||||||
|
* cc -c -I/usr/local/python/include fpectlmodule.c
|
||||||
|
* ld -shared -o fpectlmodule.so fpectlmodule.o -lfpe
|
||||||
|
*/
|
||||||
|
#include <sigfpe.h>
|
||||||
|
typedef void user_routine (unsigned[5], int[2]);
|
||||||
|
typedef void abort_routine (unsigned long);
|
||||||
|
handle_sigfpes(_OFF, 0,
|
||||||
|
(user_routine *)0,
|
||||||
|
_TURN_OFF_HANDLER_ON_ERROR,
|
||||||
|
(abort_routine*)0);
|
||||||
|
handle_sigfpes(_ON, _EN_OVERFL | _EN_DIVZERO | _EN_INVALID,
|
||||||
|
(user_routine *)0,
|
||||||
|
_ABORT_ON_ERROR,
|
||||||
|
(abort_routine*)0);
|
||||||
|
signal(SIGFPE, handler);
|
||||||
|
|
||||||
|
/*-- SunOS and Solaris ----------------------------------------------------*/
|
||||||
|
#elif defined(sun)
|
||||||
|
/* References: ieee_handler, ieee_sun, ieee_functions, and ieee_flags
|
||||||
|
man pages (SunOS or Solaris)
|
||||||
|
cc -c -I/usr/local/python/include fpectlmodule.c
|
||||||
|
ld -G -o fpectlmodule.so -L/opt/SUNWspro/lib fpectlmodule.o -lsunmath -lm
|
||||||
|
*/
|
||||||
|
#include <math.h>
|
||||||
|
char *mode="exception", *in="all", *out;
|
||||||
|
(void) nonstandard_arithmetic();
|
||||||
|
(void) ieee_flags("clearall",mode,in,&out);
|
||||||
|
(void) ieee_handler("set","common",(sigfpe_handler_type)handler);
|
||||||
|
signal(SIGFPE, handler);
|
||||||
|
|
||||||
|
/*-- HPUX -----------------------------------------------------------------*/
|
||||||
|
#elif defined(__hppa) || defined(hppa)
|
||||||
|
/* References: fpsetmask man page */
|
||||||
|
/* cc -Aa +z -c -I/usr/local/python/include fpectlmodule.c */
|
||||||
|
/* ld -b -o fpectlmodule.sl fpectlmodule.o -lm */
|
||||||
|
#include <math.h>
|
||||||
|
fpsetdefaults();
|
||||||
|
signal(SIGFPE, handler);
|
||||||
|
|
||||||
|
/*-- IBM AIX --------------------------------------------------------------*/
|
||||||
|
#elif defined(__AIX) || defined(_AIX)
|
||||||
|
/* References: fp_trap, fp_enable man pages */
|
||||||
|
#include <fptrap.h>
|
||||||
|
fp_trap(FP_TRAP_SYNC);
|
||||||
|
fp_enable(TRP_INVALID | TRP_DIV_BY_ZERO | TRP_OVERFLOW);
|
||||||
|
signal(SIGFPE, handler);
|
||||||
|
|
||||||
|
/*-- DEC ALPHA OSF --------------------------------------------------------*/
|
||||||
|
#elif defined(__alpha)
|
||||||
|
/* References: exception_intro, ieee man pages */
|
||||||
|
/* cc -c -I/usr/local/python/include fpectlmodule.c */
|
||||||
|
/* ld -shared -o fpectlmodule.so fpectlmodule.o */
|
||||||
|
#include <machine/fpu.h>
|
||||||
|
unsigned long fp_control =
|
||||||
|
IEEE_TRAP_ENABLE_INV | IEEE_TRAP_ENABLE_DZE | IEEE_TRAP_ENABLE_OVF;
|
||||||
|
ieee_set_fp_control(fp_control);
|
||||||
|
signal(SIGFPE, handler);
|
||||||
|
|
||||||
|
/*-- Cray Unicos ----------------------------------------------------------*/
|
||||||
|
#elif defined(cray)
|
||||||
|
/* UNICOS delivers SIGFPE by default, but no matherr */
|
||||||
|
#ifdef HAS_LIBMSET
|
||||||
|
libmset(-1);
|
||||||
|
#endif
|
||||||
|
signal(SIGFPE, handler);
|
||||||
|
|
||||||
|
/*-- Linux ----------------------------------------------------------------*/
|
||||||
|
#elif defined(linux)
|
||||||
|
/* Linux delivers SIGFPE by default,
|
||||||
|
except for log(0), atanh(-1), 0.^0.
|
||||||
|
*/
|
||||||
|
signal(SIGFPE, handler);
|
||||||
|
|
||||||
|
/*-- NeXT -----------------------------------------------------------------*/
|
||||||
|
#elif defined(NeXT) && defined(m68k) && defined(__GNUC__)
|
||||||
|
/* NeXT needs explicit csr set to generate SIGFPE */
|
||||||
|
asm("fmovel #0x1400,fpcr"); /* set OVFL and ZD bits */
|
||||||
|
signal(SIGFPE, handler);
|
||||||
|
|
||||||
|
/*-- Microsoft Windows, NT ------------------------------------------------*/
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
/* Reference: Visual C++ Books Online 4.2,
|
||||||
|
Run-Time Library Reference, _control87, _controlfp */
|
||||||
|
#include <float.h>
|
||||||
|
unsigned int cw = _EM_INVALID | _EM_ZERODIVIDE | _EM_OVERFLOW;
|
||||||
|
(void)_controlfp(0, cw);
|
||||||
|
signal(SIGFPE, handler);
|
||||||
|
|
||||||
|
/*-- Give Up --------------------------------------------------------------*/
|
||||||
|
#else
|
||||||
|
fputs("Operation not implemented\n", stderr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *turnoff_sigfpe(PyObject *self,PyObject *args)
|
||||||
|
{
|
||||||
|
fputs("Operation not implemented\n", stderr);
|
||||||
|
Py_INCREF (Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sigfpe_handler(int signo)
|
||||||
|
{
|
||||||
|
fpe_reset(sigfpe_handler);
|
||||||
|
if(PyFPE_counter) {
|
||||||
|
longjmp(PyFPE_jbuf, 1);
|
||||||
|
} else {
|
||||||
|
Py_FatalError("Unprotected floating point exception");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initfpectl(void)
|
||||||
|
{
|
||||||
|
PyObject *m, *d;
|
||||||
|
static int already_initialized = 0;
|
||||||
|
|
||||||
|
if (already_initialized) return;
|
||||||
|
m = Py_InitModule("fpectl", fpectl_methods);
|
||||||
|
d = PyModule_GetDict(m);
|
||||||
|
fpe_error = PyString_FromString("fpectl.error");
|
||||||
|
PyDict_SetItemString(d, "error", fpe_error);
|
||||||
|
|
||||||
|
if (PyErr_Occurred())
|
||||||
|
Py_FatalError("Cannot initialize module fpectl");
|
||||||
|
already_initialized = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
228
Modules/fpetestmodule.c
Normal file
228
Modules/fpetestmodule.c
Normal file
|
@ -0,0 +1,228 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
/ Copyright (c) 1996. \
|
||||||
|
| The Regents of the University of California. |
|
||||||
|
| All rights reserved. |
|
||||||
|
| |
|
||||||
|
| Permission to use, copy, modify, and distribute this software for |
|
||||||
|
| any purpose without fee is hereby granted, provided that this en- |
|
||||||
|
| tire notice is included in all copies of any software which is or |
|
||||||
|
| includes a copy or modification of this software and in all |
|
||||||
|
| copies of the supporting documentation for such software. |
|
||||||
|
| |
|
||||||
|
| This work was produced at the University of California, Lawrence |
|
||||||
|
| Livermore National Laboratory under contract no. W-7405-ENG-48 |
|
||||||
|
| between the U.S. Department of Energy and The Regents of the |
|
||||||
|
| University of California for the operation of UC LLNL. |
|
||||||
|
| |
|
||||||
|
| DISCLAIMER |
|
||||||
|
| |
|
||||||
|
| This software was prepared as an account of work sponsored by an |
|
||||||
|
| agency of the United States Government. Neither the United States |
|
||||||
|
| Government nor the University of California nor any of their em- |
|
||||||
|
| ployees, makes any warranty, express or implied, or assumes any |
|
||||||
|
| liability or responsibility for the accuracy, completeness, or |
|
||||||
|
| usefulness of any information, apparatus, product, or process |
|
||||||
|
| disclosed, or represents that its use would not infringe |
|
||||||
|
| privately-owned rights. Reference herein to any specific commer- |
|
||||||
|
| cial products, process, or service by trade name, trademark, |
|
||||||
|
| manufacturer, or otherwise, does not necessarily constitute or |
|
||||||
|
| imply its endorsement, recommendation, or favoring by the United |
|
||||||
|
| States Government or the University of California. The views and |
|
||||||
|
| opinions of authors expressed herein do not necessarily state or |
|
||||||
|
| reflect those of the United States Government or the University |
|
||||||
|
| of California, and shall not be used for advertising or product |
|
||||||
|
\ endorsement purposes. /
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Floating point exception test module.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Python.h"
|
||||||
|
|
||||||
|
static PyObject *fpe_error;
|
||||||
|
void initfpetest(void);
|
||||||
|
static PyObject *test(PyObject *self,PyObject *args);
|
||||||
|
static int db0(void);
|
||||||
|
static int overflow(void);
|
||||||
|
static int nest1(double);
|
||||||
|
static int nest2(double);
|
||||||
|
static double nest3(double);
|
||||||
|
|
||||||
|
static PyMethodDef fpetest_methods[] = {
|
||||||
|
{"test", (PyCFunction) test, 1},
|
||||||
|
{0,0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyObject *test(PyObject *self,PyObject *args)
|
||||||
|
{
|
||||||
|
int i = 0, r;
|
||||||
|
|
||||||
|
fprintf(stderr,"Test trapping overflow\n");
|
||||||
|
r = overflow();
|
||||||
|
if(r){
|
||||||
|
fprintf(stderr,"(Note: No exception was raised.)\n");
|
||||||
|
PyErr_Clear();
|
||||||
|
}else{
|
||||||
|
fprintf(stderr,"Trapped:: ");
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
i += r;
|
||||||
|
|
||||||
|
fprintf(stderr,"Test trapping division by zero\n");
|
||||||
|
r = db0();
|
||||||
|
if(r){
|
||||||
|
fprintf(stderr,"(Note: No exception was raised.)\n");
|
||||||
|
PyErr_Clear();
|
||||||
|
}else{
|
||||||
|
fprintf(stderr,"Trapped:: ");
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
i += r;
|
||||||
|
|
||||||
|
fprintf(stderr,"Test nested protection zones, outer zone\n");
|
||||||
|
r = nest1(0.0);
|
||||||
|
if(r){
|
||||||
|
fprintf(stderr,"(Note: No exception was raised.)\n");
|
||||||
|
PyErr_Clear();
|
||||||
|
}else{
|
||||||
|
fprintf(stderr,"Trapped:: ");
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
i += r;
|
||||||
|
|
||||||
|
fprintf(stderr,"Test nested protection zones, inner zone\n");
|
||||||
|
fprintf(stderr,"(Note: Return will apparently come from outer zone.)\n");
|
||||||
|
r = nest1(1.0);
|
||||||
|
if(r){
|
||||||
|
fprintf(stderr,"(Note: No exception was raised.)\n");
|
||||||
|
PyErr_Clear();
|
||||||
|
}else{
|
||||||
|
fprintf(stderr,"Trapped:: ");
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
i += r;
|
||||||
|
|
||||||
|
fprintf(stderr,"Test nested protection zones, trailing outer zone\n");
|
||||||
|
r = nest1(2.0);
|
||||||
|
if(r){
|
||||||
|
fprintf(stderr,"(Note: No exception was raised.)\n");
|
||||||
|
PyErr_Clear();
|
||||||
|
}else{
|
||||||
|
fprintf(stderr,"Trapped:: ");
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
i += r;
|
||||||
|
|
||||||
|
fprintf(stderr,"Test nested function calls, prior error\n");
|
||||||
|
r = nest2(0.0);
|
||||||
|
if(r){
|
||||||
|
fprintf(stderr,"(Note: No exception was raised.)\n");
|
||||||
|
PyErr_Clear();
|
||||||
|
}else{
|
||||||
|
fprintf(stderr,"Trapped:: ");
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
i += r;
|
||||||
|
|
||||||
|
fprintf(stderr,"Test nested function calls, interior error\n");
|
||||||
|
r = nest2(1.0);
|
||||||
|
if(r){
|
||||||
|
fprintf(stderr,"(Note: No exception was raised.)\n");
|
||||||
|
PyErr_Clear();
|
||||||
|
}else{
|
||||||
|
fprintf(stderr,"Trapped:: ");
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
i += r;
|
||||||
|
|
||||||
|
fprintf(stderr,"Test nested function calls, trailing error\n");
|
||||||
|
r = nest2(2.0);
|
||||||
|
if(r){
|
||||||
|
fprintf(stderr,"(Note: No exception was raised.)\n");
|
||||||
|
PyErr_Clear();
|
||||||
|
}else{
|
||||||
|
fprintf(stderr,"Trapped:: ");
|
||||||
|
PyErr_Print();
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
i += r;
|
||||||
|
|
||||||
|
fprintf(stderr,"Number of tests failed: %d\n", i);
|
||||||
|
Py_INCREF (Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nest1(double x)
|
||||||
|
{
|
||||||
|
double a = 1.0;
|
||||||
|
PyFPE_START_PROTECT("Division by zero, outer zone", return 0)
|
||||||
|
a = 1./x;
|
||||||
|
PyFPE_START_PROTECT("Division by zero, inner zone", return 0)
|
||||||
|
a = 1./(1. - x);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
|
a = 1./(2. - x);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nest2(double x)
|
||||||
|
{
|
||||||
|
double a = 1.0;
|
||||||
|
PyFPE_START_PROTECT("Division by zero, prior error", return 0)
|
||||||
|
a = 1./x;
|
||||||
|
a = nest3(x);
|
||||||
|
a = 1./(2. - x);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double nest3(double x)
|
||||||
|
{
|
||||||
|
double result;
|
||||||
|
PyFPE_START_PROTECT("Division by zero, nest3 error", return 0)
|
||||||
|
result = 1./(1. - x);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int db0(void)
|
||||||
|
{
|
||||||
|
double a = 1.0;
|
||||||
|
PyFPE_START_PROTECT("Division by zero", return 0)
|
||||||
|
a = 1./(a - 1.);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int overflow(void)
|
||||||
|
{
|
||||||
|
double a, b = 1.e200;
|
||||||
|
PyFPE_START_PROTECT("Overflow", return 0)
|
||||||
|
a = b*b;
|
||||||
|
PyFPE_END_PROTECT
|
||||||
|
return(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initfpetest(void)
|
||||||
|
{
|
||||||
|
PyObject *m, *d;
|
||||||
|
|
||||||
|
m = Py_InitModule("fpetest", fpetest_methods);
|
||||||
|
d = PyModule_GetDict(m);
|
||||||
|
fpe_error = PyString_FromString("fpetest.error");
|
||||||
|
PyDict_SetItemString(d, "error", fpe_error);
|
||||||
|
|
||||||
|
if (PyErr_Occurred())
|
||||||
|
Py_FatalError("Cannot initialize module fpetest");
|
||||||
|
}
|
|
@ -387,8 +387,10 @@ PyObject *args;
|
||||||
iclose(image);
|
iclose(image);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
PyFPE_START_PROTECT("readscaled", return 0)
|
||||||
xfac = (float)xsize/(float)xwtd;
|
xfac = (float)xsize/(float)xwtd;
|
||||||
yfac = (float)ysize/(float)ywtd;
|
yfac = (float)ysize/(float)ywtd;
|
||||||
|
PyFPE_END_PROTECT
|
||||||
cdatap = PyString_AsString(rv);
|
cdatap = PyString_AsString(rv);
|
||||||
idatap = (long *)cdatap;
|
idatap = (long *)cdatap;
|
||||||
|
|
||||||
|
|
|
@ -80,7 +80,9 @@ math_1(args, func)
|
||||||
if (! PyArg_Parse(args, "d", &x))
|
if (! PyArg_Parse(args, "d", &x))
|
||||||
return NULL;
|
return NULL;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
PyFPE_START_PROTECT("in math_1", return 0)
|
||||||
x = (*func)(x);
|
x = (*func)(x);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
CHECK(x);
|
CHECK(x);
|
||||||
if (errno != 0)
|
if (errno != 0)
|
||||||
return math_error();
|
return math_error();
|
||||||
|
@ -97,7 +99,9 @@ math_2(args, func)
|
||||||
if (! PyArg_Parse(args, "(dd)", &x, &y))
|
if (! PyArg_Parse(args, "(dd)", &x, &y))
|
||||||
return NULL;
|
return NULL;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
PyFPE_START_PROTECT("in math_2", return 0)
|
||||||
x = (*func)(x, y);
|
x = (*func)(x, y);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
CHECK(x);
|
CHECK(x);
|
||||||
if (errno != 0)
|
if (errno != 0)
|
||||||
return math_error();
|
return math_error();
|
||||||
|
@ -173,7 +177,9 @@ math_ldexp(self, args)
|
||||||
if (! PyArg_Parse(args, "(dd)", &x, &y))
|
if (! PyArg_Parse(args, "(dd)", &x, &y))
|
||||||
return NULL;
|
return NULL;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
PyFPE_START_PROTECT("ldexp", return 0)
|
||||||
x = ldexp(x, (int)y);
|
x = ldexp(x, (int)y);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
CHECK(x);
|
CHECK(x);
|
||||||
if (errno != 0)
|
if (errno != 0)
|
||||||
return math_error();
|
return math_error();
|
||||||
|
|
|
@ -1488,6 +1488,8 @@ mpz_float(self)
|
||||||
/* let those bits come, let those bits go,
|
/* let those bits come, let those bits go,
|
||||||
e.g. dismantle mpzscratch, build PyFloatObject */
|
e.g. dismantle mpzscratch, build PyFloatObject */
|
||||||
|
|
||||||
|
/* Can this overflow? Dunno, protect against that possibility. */
|
||||||
|
PyFPE_START_PROTECT("mpz_float", return 0)
|
||||||
x = 0.0;
|
x = 0.0;
|
||||||
mulstate = 1.0;
|
mulstate = 1.0;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
@ -1495,6 +1497,7 @@ mpz_float(self)
|
||||||
mulstate *= multiplier;
|
mulstate *= multiplier;
|
||||||
mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
|
mpz_div_2exp(&mpzscratch, &mpzscratch, BITS_PER_MP_LIMB);
|
||||||
}
|
}
|
||||||
|
PyFPE_END_PROTECT
|
||||||
|
|
||||||
assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
|
assert(mpz_cmp_ui(&mpzscratch, (unsigned long int)0) == 0);
|
||||||
mpz_clear(&mpzscratch);
|
mpz_clear(&mpzscratch);
|
||||||
|
|
|
@ -661,7 +661,9 @@ strop_atof(self, args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
PyFPE_START_PROTECT("strop_atof", return 0)
|
||||||
x = strtod(s, &end);
|
x = strtod(s, &end);
|
||||||
|
PyFPE_END_PROTECT
|
||||||
while (*end && isspace(Py_CHARMASK(*end)))
|
while (*end && isspace(Py_CHARMASK(*end)))
|
||||||
end++;
|
end++;
|
||||||
if (*end != '\0') {
|
if (*end != '\0') {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue