2024-01-01 18:12:26 +00:00
|
|
|
/* Copyright (C) 1997-2024 Free Software Foundation, Inc.
|
1997-07-06 22:02:42 +00:00
|
|
|
This file is part of the GNU C Library.
|
|
|
|
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
2001-07-06 04:58:11 +00:00
|
|
|
modify it under the terms of the GNU Lesser General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2.1 of the License, or (at your option) any later version.
|
1997-07-06 22:02:42 +00:00
|
|
|
|
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
2001-07-06 04:58:11 +00:00
|
|
|
Lesser General Public License for more details.
|
1997-07-06 22:02:42 +00:00
|
|
|
|
2001-07-06 04:58:11 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2012-02-09 23:18:22 +00:00
|
|
|
License along with the GNU C Library; if not, see
|
Prefer https to http for gnu.org and fsf.org URLs
Also, change sources.redhat.com to sourceware.org.
This patch was automatically generated by running the following shell
script, which uses GNU sed, and which avoids modifying files imported
from upstream:
sed -ri '
s,(http|ftp)(://(.*\.)?(gnu|fsf|sourceware)\.org($|[^.]|\.[^a-z])),https\2,g
s,(http|ftp)(://(.*\.)?)sources\.redhat\.com($|[^.]|\.[^a-z]),https\2sourceware.org\4,g
' \
$(find $(git ls-files) -prune -type f \
! -name '*.po' \
! -name 'ChangeLog*' \
! -path COPYING ! -path COPYING.LIB \
! -path manual/fdl-1.3.texi ! -path manual/lgpl-2.1.texi \
! -path manual/texinfo.tex ! -path scripts/config.guess \
! -path scripts/config.sub ! -path scripts/install-sh \
! -path scripts/mkinstalldirs ! -path scripts/move-if-change \
! -path INSTALL ! -path locale/programs/charmap-kw.h \
! -path po/libc.pot ! -path sysdeps/gnu/errlist.c \
! '(' -name configure \
-execdir test -f configure.ac -o -f configure.in ';' ')' \
! '(' -name preconfigure \
-execdir test -f preconfigure.ac ';' ')' \
-print)
and then by running 'make dist-prepare' to regenerate files built
from the altered files, and then executing the following to cleanup:
chmod a+x sysdeps/unix/sysv/linux/riscv/configure
# Omit irrelevant whitespace and comment-only changes,
# perhaps from a slightly-different Autoconf version.
git checkout -f \
sysdeps/csky/configure \
sysdeps/hppa/configure \
sysdeps/riscv/configure \
sysdeps/unix/sysv/linux/csky/configure
# Omit changes that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/powerpc/powerpc64/ppc-mcount.S: trailing lines
git checkout -f \
sysdeps/powerpc/powerpc64/ppc-mcount.S \
sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
# Omit change that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S: last line does not end in newline
git checkout -f sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S
2019-09-07 05:40:42 +00:00
|
|
|
<https://www.gnu.org/licenses/>. */
|
1997-07-06 22:02:42 +00:00
|
|
|
|
1999-10-31 17:37:43 +00:00
|
|
|
/* Tests for ISO C99 7.6: Floating-point environment */
|
1997-06-27 23:09:40 +00:00
|
|
|
|
|
|
|
#ifndef _GNU_SOURCE
|
|
|
|
# define _GNU_SOURCE
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <complex.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <float.h>
|
|
|
|
#include <fenv.h>
|
|
|
|
|
|
|
|
#include <errno.h>
|
1997-07-06 22:02:42 +00:00
|
|
|
#include <signal.h>
|
1997-06-27 23:09:40 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
1997-07-06 22:02:42 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/wait.h>
|
1998-01-21 17:04:36 +00:00
|
|
|
#include <sys/resource.h>
|
2014-04-17 08:39:27 +00:00
|
|
|
#include <math-tests.h>
|
1997-06-27 23:09:40 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
Since not all architectures might define all exceptions, we define
|
|
|
|
a private set and map accordingly.
|
|
|
|
*/
|
|
|
|
#define NO_EXC 0
|
|
|
|
#define INEXACT_EXC 0x1
|
|
|
|
#define DIVBYZERO_EXC 0x2
|
|
|
|
#define UNDERFLOW_EXC 0x04
|
|
|
|
#define OVERFLOW_EXC 0x08
|
|
|
|
#define INVALID_EXC 0x10
|
|
|
|
#define ALL_EXC \
|
Break some lines before not after operators.
The GNU Coding Standards specify that line breaks in expressions
should go before an operator, not after one. This patch fixes various
code to do this. It only changes code that appears to be mostly
following GNU style anyway, not files and directories with
substantially different formatting. It is not exhaustive even for
files using GNU style (for example, changes to sysdeps files are
deferred for subsequent cleanups). Some files changed are shared with
gnulib, but most are specific to glibc. Changes were made manually,
with places to change found by grep (so some cases, e.g. where the
operator was followed by a comment at end of line, are particularly
liable to have been missed by grep, but I did include cases where the
operator was followed by backslash-newline).
This patch generally does not attempt to address other coding style
issues in the expressions changed (for example, missing spaces before
'(', or lack of parentheses to ensure indentation of continuation
lines properly reflects operator precedence).
Tested for x86_64, and with build-many-glibcs.py.
* benchtests/bench-memmem.c (simple_memmem): Break lines before
rather than after operators.
* benchtests/bench-skeleton.c (TIMESPEC_AFTER): Likewise.
* crypt/md5.c (md5_finish_ctx): Likewise.
* crypt/sha256.c (__sha256_finish_ctx): Likewise.
* crypt/sha512.c (__sha512_finish_ctx): Likewise.
* elf/cache.c (load_aux_cache): Likewise.
* elf/dl-load.c (open_verify): Likewise.
* elf/get-dynamic-info.h (elf_get_dynamic_info): Likewise.
* elf/readelflib.c (process_elf_file): Likewise.
* elf/rtld.c (dl_main): Likewise.
* elf/sprof.c (generate_call_graph): Likewise.
* hurd/ctty-input.c (_hurd_ctty_input): Likewise.
* hurd/ctty-output.c (_hurd_ctty_output): Likewise.
* hurd/dtable.c (reauth_dtable): Likewise.
* hurd/getdport.c (__getdport): Likewise.
* hurd/hurd/signal.h (_hurd_interrupted_rpc_timeout): Likewise.
* hurd/hurd/sigpreempt.h (HURD_PREEMPT_SIGNAL_P): Likewise.
* hurd/hurdfault.c (_hurdsig_fault_catch_exception_raise):
Likewise.
* hurd/hurdioctl.c (fioctl): Likewise.
* hurd/hurdselect.c (_hurd_select): Likewise.
* hurd/hurdsig.c (_hurdsig_abort_rpcs): Likewise.
(STOPSIGS): Likewise.
* hurd/hurdstartup.c (_hurd_startup): Likewise.
* hurd/intr-msg.c (_hurd_intr_rpc_mach_msg): Likewise.
* hurd/lookup-retry.c (__hurd_file_name_lookup_retry): Likewise.
* hurd/msgportdemux.c (msgport_server): Likewise.
* hurd/setauth.c (_hurd_setauth): Likewise.
* include/features.h (__GLIBC_USE_DEPRECATED_SCANF): Likewise.
* libio/libioP.h [IO_DEBUG] (CHECK_FILE): Likewise.
* locale/programs/ld-ctype.c (set_class_defaults): Likewise.
* localedata/tests-mbwc/tst_swscanf.c (tst_swscanf): Likewise.
* login/tst-utmp.c (do_check): Likewise.
(simulate_login): Likewise.
* mach/lowlevellock.h (lll_lock): Likewise.
(lll_trylock): Likewise.
* math/test-fenv.c (ALL_EXC): Likewise.
* math/test-fenvinline.c (ALL_EXC): Likewise.
* misc/sys/cdefs.h (__attribute_deprecated_msg__): Likewise.
* nis/nis_call.c (__do_niscall3): Likewise.
* nis/nis_callback.c (cb_prog_1): Likewise.
* nis/nis_defaults.c (searchaccess): Likewise.
* nis/nis_findserv.c (__nis_findfastest_with_timeout): Likewise.
* nis/nis_ismember.c (internal_ismember): Likewise.
* nis/nis_local_names.c (nis_local_principal): Likewise.
* nis/nss_nis/nis-rpc.c (_nss_nis_getrpcbyname_r): Likewise.
* nis/nss_nisplus/nisplus-netgrp.c (_nss_nisplus_getnetgrent_r):
Likewise.
* nis/ypclnt.c (yp_match): Likewise.
(yp_first): Likewise.
(yp_next): Likewise.
(yp_master): Likewise.
(yp_order): Likewise.
* nscd/hstcache.c (cache_addhst): Likewise.
* nscd/initgrcache.c (addinitgroupsX): Likewise.
* nss/nss_compat/compat-pwd.c (copy_pwd_changes): Likewise.
(internal_getpwuid_r): Likewise.
* nss/nss_compat/compat-spwd.c (copy_spwd_changes): Likewise.
* posix/glob.h (__GLOB_FLAGS): Likewise.
* posix/regcomp.c (peek_token): Likewise.
(peek_token_bracket): Likewise.
(parse_expression): Likewise.
* posix/regexec.c (sift_states_iter_mb): Likewise.
(check_node_accept_bytes): Likewise.
* posix/tst-spawn3.c (do_test): Likewise.
* posix/wordexp-test.c (testit): Likewise.
* posix/wordexp.c (parse_tilde): Likewise.
(exec_comm): Likewise.
* posix/wordexp.h (__WRDE_FLAGS): Likewise.
* resource/vtimes.c (TIMEVAL_TO_VTIMES): Likewise.
* setjmp/sigjmp.c (__sigjmp_save): Likewise.
* stdio-common/printf_fp.c (__printf_fp_l): Likewise.
* stdio-common/tst-fileno.c (do_test): Likewise.
* stdio-common/vfprintf-internal.c (vfprintf): Likewise.
* stdlib/strfmon_l.c (__vstrfmon_l_internal): Likewise.
* stdlib/strtod_l.c (round_and_return): Likewise.
(____STRTOF_INTERNAL): Likewise.
* stdlib/tst-strfrom.h (TEST_STRFROM): Likewise.
* string/strcspn.c (STRCSPN): Likewise.
* string/test-memmem.c (simple_memmem): Likewise.
* termios/tcsetattr.c (tcsetattr): Likewise.
* time/alt_digit.c (_nl_parse_alt_digit): Likewise.
* time/asctime.c (asctime_internal): Likewise.
* time/strptime_l.c (__strptime_internal): Likewise.
* time/sys/time.h (timercmp): Likewise.
* time/tzfile.c (__tzfile_compute): Likewise.
2019-02-22 01:32:36 +00:00
|
|
|
(INEXACT_EXC | DIVBYZERO_EXC | UNDERFLOW_EXC | OVERFLOW_EXC \
|
|
|
|
| INVALID_EXC)
|
1997-06-27 23:09:40 +00:00
|
|
|
|
|
|
|
static int count_errors;
|
|
|
|
|
2014-12-30 19:11:13 +00:00
|
|
|
#if FE_ALL_EXCEPT
|
1997-06-27 23:09:40 +00:00
|
|
|
/* Test whether a given exception was raised. */
|
|
|
|
static void
|
|
|
|
test_single_exception (short int exception,
|
|
|
|
short int exc_flag,
|
|
|
|
fexcept_t fe_flag,
|
|
|
|
const char *flag_name)
|
|
|
|
{
|
|
|
|
if (exception & exc_flag)
|
|
|
|
{
|
|
|
|
if (fetestexcept (fe_flag))
|
|
|
|
printf (" Pass: Exception \"%s\" is set\n", flag_name);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf (" Fail: Exception \"%s\" is not set\n", flag_name);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (fetestexcept (fe_flag))
|
|
|
|
{
|
|
|
|
printf (" Fail: Exception \"%s\" is set\n", flag_name);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf (" Pass: Exception \"%s\" is not set\n", flag_name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-12-30 19:11:13 +00:00
|
|
|
#endif
|
1997-06-27 23:09:40 +00:00
|
|
|
|
|
|
|
static void
|
1997-07-24 01:36:01 +00:00
|
|
|
test_exceptions (const char *test_name, short int exception,
|
|
|
|
int ignore_inexact)
|
1997-06-27 23:09:40 +00:00
|
|
|
{
|
|
|
|
printf ("Test: %s\n", test_name);
|
|
|
|
#ifdef FE_DIVBYZERO
|
|
|
|
test_single_exception (exception, DIVBYZERO_EXC, FE_DIVBYZERO,
|
|
|
|
"DIVBYZERO");
|
|
|
|
#endif
|
|
|
|
#ifdef FE_INVALID
|
|
|
|
test_single_exception (exception, INVALID_EXC, FE_INVALID,
|
|
|
|
"INVALID");
|
|
|
|
#endif
|
|
|
|
#ifdef FE_INEXACT
|
1997-07-24 01:36:01 +00:00
|
|
|
if (!ignore_inexact)
|
|
|
|
test_single_exception (exception, INEXACT_EXC, FE_INEXACT,
|
|
|
|
"INEXACT");
|
1997-06-27 23:09:40 +00:00
|
|
|
#endif
|
|
|
|
#ifdef FE_UNDERFLOW
|
|
|
|
test_single_exception (exception, UNDERFLOW_EXC, FE_UNDERFLOW,
|
|
|
|
"UNDERFLOW");
|
|
|
|
#endif
|
|
|
|
#ifdef FE_OVERFLOW
|
|
|
|
test_single_exception (exception, OVERFLOW_EXC, FE_OVERFLOW,
|
|
|
|
"OVERFLOW");
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
1997-07-06 22:02:42 +00:00
|
|
|
static void
|
|
|
|
print_rounding (int rounding)
|
|
|
|
{
|
|
|
|
|
1998-02-26 11:20:59 +00:00
|
|
|
switch (rounding)
|
|
|
|
{
|
1997-07-06 22:02:42 +00:00
|
|
|
#ifdef FE_TONEAREST
|
1998-02-26 11:20:59 +00:00
|
|
|
case FE_TONEAREST:
|
|
|
|
printf ("TONEAREST");
|
|
|
|
break;
|
1997-07-06 22:02:42 +00:00
|
|
|
#endif
|
|
|
|
#ifdef FE_UPWARD
|
1998-02-26 11:20:59 +00:00
|
|
|
case FE_UPWARD:
|
|
|
|
printf ("UPWARD");
|
|
|
|
break;
|
1997-07-06 22:02:42 +00:00
|
|
|
#endif
|
|
|
|
#ifdef FE_DOWNWARD
|
1998-02-26 11:20:59 +00:00
|
|
|
case FE_DOWNWARD:
|
|
|
|
printf ("DOWNWARD");
|
|
|
|
break;
|
1997-07-06 22:02:42 +00:00
|
|
|
#endif
|
|
|
|
#ifdef FE_TOWARDZERO
|
1998-02-26 11:20:59 +00:00
|
|
|
case FE_TOWARDZERO:
|
|
|
|
printf ("TOWARDZERO");
|
|
|
|
break;
|
1997-07-06 22:02:42 +00:00
|
|
|
#endif
|
1998-02-26 11:20:59 +00:00
|
|
|
}
|
1997-07-06 22:02:42 +00:00
|
|
|
printf (".\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_rounding (const char *test_name, int rounding_mode)
|
|
|
|
{
|
|
|
|
int curr_rounding = fegetround ();
|
|
|
|
|
|
|
|
printf ("Test: %s\n", test_name);
|
|
|
|
if (curr_rounding == rounding_mode)
|
|
|
|
{
|
|
|
|
printf (" Pass: Rounding mode is ");
|
|
|
|
print_rounding (curr_rounding);
|
|
|
|
}
|
1998-02-26 11:20:59 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
++count_errors;
|
|
|
|
printf (" Fail: Rounding mode is ");
|
|
|
|
print_rounding (curr_rounding);
|
|
|
|
}
|
1997-07-06 22:02:42 +00:00
|
|
|
}
|
|
|
|
|
1997-06-27 23:09:40 +00:00
|
|
|
|
2014-12-30 19:11:13 +00:00
|
|
|
#if FE_ALL_EXCEPT
|
1997-06-27 23:09:40 +00:00
|
|
|
static void
|
|
|
|
set_single_exc (const char *test_name, int fe_exc, fexcept_t exception)
|
|
|
|
{
|
|
|
|
char str[200];
|
1997-07-24 01:36:01 +00:00
|
|
|
/* The standard allows the inexact exception to be set together with the
|
|
|
|
underflow and overflow exceptions. So ignore the inexact flag if the
|
|
|
|
others are raised. */
|
|
|
|
int ignore_inexact = (fe_exc & (UNDERFLOW_EXC | OVERFLOW_EXC)) != 0;
|
1997-06-27 23:09:40 +00:00
|
|
|
|
|
|
|
strcpy (str, test_name);
|
|
|
|
strcat (str, ": set flag, with rest not set");
|
|
|
|
feclearexcept (FE_ALL_EXCEPT);
|
|
|
|
feraiseexcept (exception);
|
1997-07-24 01:36:01 +00:00
|
|
|
test_exceptions (str, fe_exc, ignore_inexact);
|
1997-06-27 23:09:40 +00:00
|
|
|
|
|
|
|
strcpy (str, test_name);
|
|
|
|
strcat (str, ": clear flag, rest also unset");
|
|
|
|
feclearexcept (exception);
|
1997-07-24 01:36:01 +00:00
|
|
|
test_exceptions (str, NO_EXC, ignore_inexact);
|
1997-06-27 23:09:40 +00:00
|
|
|
|
|
|
|
strcpy (str, test_name);
|
|
|
|
strcat (str, ": set flag, with rest set");
|
|
|
|
feraiseexcept (FE_ALL_EXCEPT ^ exception);
|
|
|
|
feraiseexcept (exception);
|
1997-07-24 01:36:01 +00:00
|
|
|
test_exceptions (str, ALL_EXC, 0);
|
1997-06-27 23:09:40 +00:00
|
|
|
|
|
|
|
strcpy (str, test_name);
|
|
|
|
strcat (str, ": clear flag, leave rest set");
|
|
|
|
feclearexcept (exception);
|
1997-07-24 01:36:01 +00:00
|
|
|
test_exceptions (str, ALL_EXC ^ fe_exc, 0);
|
1997-06-27 23:09:40 +00:00
|
|
|
}
|
2023-11-02 14:15:55 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
update_single_exc (const char *test_name, const fenv_t *envp, int fe_exc,
|
|
|
|
int fe_exc_clear, int exception)
|
|
|
|
{
|
|
|
|
char str[200];
|
|
|
|
/* The standard allows the inexact exception to be set together with the
|
|
|
|
underflow and overflow exceptions. So ignore the inexact flag if the
|
|
|
|
others are raised. */
|
|
|
|
int ignore_inexact = (fe_exc & (UNDERFLOW_EXC | OVERFLOW_EXC)) != 0;
|
|
|
|
|
|
|
|
strcpy (str, test_name);
|
|
|
|
strcat (str, ": set flag, with rest not set");
|
|
|
|
feclearexcept (FE_ALL_EXCEPT);
|
|
|
|
feraiseexcept (exception);
|
|
|
|
feupdateenv (envp);
|
|
|
|
test_exceptions (str, fe_exc, ignore_inexact);
|
|
|
|
|
|
|
|
strcpy (str, test_name);
|
|
|
|
strcat (str, ": clear flag, rest also unset");
|
|
|
|
feclearexcept (exception);
|
|
|
|
feupdateenv (envp);
|
|
|
|
test_exceptions (str, fe_exc_clear, ignore_inexact);
|
|
|
|
}
|
2014-12-30 19:11:13 +00:00
|
|
|
#endif
|
1997-06-27 23:09:40 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
fe_tests (void)
|
|
|
|
{
|
|
|
|
/* clear all exceptions and test if all are cleared */
|
|
|
|
feclearexcept (FE_ALL_EXCEPT);
|
|
|
|
test_exceptions ("feclearexcept (FE_ALL_EXCEPT) clears all exceptions",
|
1997-07-24 01:36:01 +00:00
|
|
|
NO_EXC, 0);
|
1997-06-27 23:09:40 +00:00
|
|
|
|
2017-01-09 18:27:49 +00:00
|
|
|
/* Skip further tests here if exceptions not supported. */
|
|
|
|
if (!EXCEPTION_TESTS (float) && FE_ALL_EXCEPT != 0)
|
|
|
|
return;
|
1997-06-27 23:09:40 +00:00
|
|
|
/* raise all exceptions and test if all are raised */
|
|
|
|
feraiseexcept (FE_ALL_EXCEPT);
|
|
|
|
test_exceptions ("feraiseexcept (FE_ALL_EXCEPT) raises all exceptions",
|
1997-07-24 01:36:01 +00:00
|
|
|
ALL_EXC, 0);
|
1997-06-27 23:09:40 +00:00
|
|
|
feclearexcept (FE_ALL_EXCEPT);
|
|
|
|
|
|
|
|
#ifdef FE_DIVBYZERO
|
|
|
|
set_single_exc ("Set/Clear FE_DIVBYZERO", DIVBYZERO_EXC, FE_DIVBYZERO);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_INVALID
|
|
|
|
set_single_exc ("Set/Clear FE_INVALID", INVALID_EXC, FE_INVALID);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_INEXACT
|
|
|
|
set_single_exc ("Set/Clear FE_INEXACT", INEXACT_EXC, FE_INEXACT);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_UNDERFLOW
|
|
|
|
set_single_exc ("Set/Clear FE_UNDERFLOW", UNDERFLOW_EXC, FE_UNDERFLOW);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_OVERFLOW
|
|
|
|
set_single_exc ("Set/Clear FE_OVERFLOW", OVERFLOW_EXC, FE_OVERFLOW);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2014-12-30 19:11:13 +00:00
|
|
|
#if FE_ALL_EXCEPT
|
2023-11-02 14:15:55 +00:00
|
|
|
static const char *
|
|
|
|
funcname (int (*func)(const fenv_t *))
|
|
|
|
{
|
|
|
|
if (func == fesetenv)
|
|
|
|
return "fesetenv";
|
|
|
|
else if (func == feupdateenv)
|
|
|
|
return "feupdateenv";
|
|
|
|
__builtin_unreachable ();
|
|
|
|
}
|
|
|
|
|
1997-07-06 22:02:42 +00:00
|
|
|
/* Test that program aborts with no masked interrupts */
|
|
|
|
static void
|
2023-11-02 14:15:55 +00:00
|
|
|
feenv_nomask_test (const char *flag_name, int fe_exc, int (*func)(const fenv_t *))
|
1997-07-06 22:02:42 +00:00
|
|
|
{
|
2014-12-30 19:11:13 +00:00
|
|
|
# if defined FE_NOMASK_ENV
|
1997-07-06 22:02:42 +00:00
|
|
|
int status;
|
|
|
|
pid_t pid;
|
2014-04-17 08:39:27 +00:00
|
|
|
|
|
|
|
if (!EXCEPTION_ENABLE_SUPPORTED (FE_ALL_EXCEPT)
|
2023-11-02 14:15:55 +00:00
|
|
|
&& func (FE_NOMASK_ENV) != 0)
|
Update.
1997-08-10 18:48 Ulrich Drepper <drepper@cygnus.com>
* Makeconfig: Define build-programs to no if not set and $(config-os)
is none.
* Makerules (+depfiles): Don't add $(others) if not build-programs.
* Rules (others): Don't depend on $(install-bin), $(install-rootbin)
and $(install-sbin) if not build-programs.
* Makefile (subdirs): Remove login.
* sysdeps/mach/hurd/Subdirs: Add login.
* sysdeps/unix/Subdirs: Add login.
* sysdeps/generic/sys/mman.h: Test feature macros before defining
non-POSIX things. Add MAP_FAILED.
* sysdeps/unix/bsd/osf/sys/mman.h: Likewise.
* sysdeps/unix/bsd/sun/sunos4/sys/mman.h: Likewise.
* sysdeps/unix/bsd/ultrix4/sys/mman.h: Likewise.
* sysdeps/unix/sysv/irix4/sys/mman.h: Likewise.
* sysdeps/unix/sysv/linux/sys/mman.h: Rewrite to not use kernel header
but bits/mman.h. Test feature macros before definitions non-POSIX
functions.
* sysdeps/unix/sysv/linux/alpha/bits/mman.h: New file.
* sysdeps/unix/sysv/linux/i386/bits/mman.h: New file.
* sysdeps/unix/sysv/linux/m68k/bits/mman.h: New file.
* sysdeps/unix/sysv/linux/mips/bits/mman.h: New file.
* sysdeps/unix/sysv/linux/powerpc/bits/mman.h: New file.
* sysdeps/unix/sysv/linux/sparc/bits/mman.h: New file.
* sysdeps/unix/sysv/linux/sparc64/bits/mman.h: New file.
* sysdeps/unix/sysv/linux/alpha/Dist: Add bits/mman.h.
* sysdeps/unix/sysv/linux/i386/Dist: Likewise.
* sysdeps/unix/sysv/linux/m68k/Dist: Likewise.
* sysdeps/unix/sysv/linux/mips/Dist: Likewise.
* sysdeps/unix/sysv/linux/powerpc/Dist: Likewise.
* sysdeps/unix/sysv/linux/sparc/Dist: Likewise.
* sysdeps/unix/sysv/linux/sparc64/Dist: New file. Likewise.
* catgets/open_catalog.c (__open_catalog): Compare result of mmap
with MAP_FAILED and not -1.
* elf/dl-load.c (_dl_map_object_from_fd): Likewise.
* elf/dl-minimal.c (malloc): Likewise.
* elf/dl-misc.c (_dl_sysdep_read_whole_file): Likewise.
* locale/loadlocale.c (_nl_load_locale): Likewise.
* locale/programs/localedef.c: Likewise.
* malloc/malloc.c (mmap_chunk): Likewise.
(new_heap): Likewise.
* string/stratcliff.c: Likewise.
* string/tester.c: Add tests for stpcpy.
* gmon/gmon.c (__monstartup): Use calloc instead of malloc+memset.
* gmon/sys/gmon.h: Add prototype for write_profiling.
* elf/dl-profile.c: Add decsriptions and implement reading of
existing data in profiling file.
* gmon/sys/gmon_out.h (GMON_SHOBJ_VERSION): New macro for shared
lib profiling data.
* sysdeps/stub/bits/libc-lock.h (__libc_once_define): Add new first
parameter for class.
* inet/inet_ntoa.c: Make once control variable static.
Correctly handle case where key cannot be retrieved.
* inet/Makefile (tests): Add tst-ntoa.
* inet/tst-ntoa.c: New file.
* manual/time.texi: Document localtime_r, gmtime_r, asctime_r, and
ctime_r.
Mention that tzname values must not be changed.
* manual/users.texi: Document UTMP/WTMP handling functions.
Mainly written by Mark Kettenis.
* math/libm-test.c (cbrt_test): Add test for number with aboslute
value < 1.0.
* nss/nss_files/files-XXX.c (internal_setent): If opening of file
failed with EGAIN return NSS_STATUS_TRYAGAIN.
* nss/nss_files/files-alias.c (internal_setent): Likewise.
* sysdeps/generic/bits/utmp.h: Pretty print.
* sysdeps/i386/i586/strcpy.S: New file. Much faster implementation.
* sysdeps/i386/i586/stpcpy.S: New file.
* sysdeps/i386/i686/Implies: Don't fall back on i586 versions since
these are less efficient than i486/i386 versions.
* sysdeps/libm-i387/e_rem_pio2.c: Add empty file to prevent the
version from libm-ieee754 be compiled since the later is not needed.
* sysdeps/libm-i387/e_rem_pio2f.c: Likewise.
* sysdeps/libm-i387/e_rem_pio2l.c: Likewise.
* sysdeps/libm-i387/k_rem_pio2.c: Likewise.
* sysdeps/libm-i387/k_rem_pio2f.c: Likewise.
* sysdeps/libm-i387/k_rem_pio2l.c: Likewise.
* sysdeps/m68k/fpu/e_rem_pio2.c: Likewise.
* sysdeps/m68k/fpu/e_rem_pio2f.c: Likewise.
* sysdeps/m68k/fpu/e_rem_pio2l.c: Likewise.
* sysdeps/m68k/fpu/k_rem_pio2.c: Likewise.
* sysdeps/m68k/fpu/k_rem_pio2f.c: Likewise.
* sysdeps/m68k/fpu/k_rem_pio2l.c: Likewise.
* sysdeps/libm-i387/s_cbrt.S: Fix several bugs.
* sysdeps/libm-i387/s_cbrtf.S: Likewise.
* sysdeps/libm-i387/s_cbrtl.S: Likewise.
* sysdeps/unix/sysv/linux/if_index.c (if_indextoname): Correct
little bug.
* sysdeps/unix/sysv/linux/bits/socket.h (struct msghdr): Make field
msg_iovlen of type int.
* time/tzfile.c: Change return type of __tzstring to char *.
* time/tzset.c: Likewise. Change definition of __tzstring.
* time/tzset.c: Interpret no DST information in user provided time
zone specification as it is meant: no DST.
Patch by Paul Eggert <eggert@twinsun.com>.
1997-07-20 03:01 Geoff Keating <geoffk@ozemail.com.au>
* sysdeps/elf/dl-load.c (add_name_to_object): New procedure.
(_dl_map_object_from_fd): Use add_name_to_object.
(_dl_map_object): If an object's SONAME is used to resolve a
dependency, add it to the list of the object's names.
* inet/getnameinfo.c: Make `domain' non-const.
* sysdeps/unix/sysv/linux/powerpc/kernel_termios.c: Clean up.
* math/test-fenv.c (feenv_nomask_test): Don't execute if
FE_NOMASK_ENV is not defined, or if fesetenv(FE_NOMASK_ENV)
sets errno to ENOSYS.
* sysdeps/powerpc/dl-machine.h: Print proper error message on
unknown reloc type (rather than using assert).
* sysdeps/unix/sysv/linux/powerpc/profil-counter.h: New file.
* sysdeps/unix/sysv/linux/powerpc/profil.c: Deleted.
1997-07-16 12:47 Geoff Keating <geoffk@ozemail.com.au>
* sysdeps/powerpc/bits/fenv.h (feraiseexcept): New optimising macro.
(feclearexcept): New optimising macro.
(FE_NOMASK_ENV): Change to procedure so it can enable exceptions.
(FE_ENABLED_ENV): Add.
(FE_NONIEEE_ENV): Add.
* sysdeps/powerpc/bits/fenv_const.c: Add __fe_enabled_env,
__fe_nonieee_env; delete __fe_nomask_env.
* sysdeps/powerpc/bits/fe_nomask.c: New file (stub warning until it
gets implemented in the kernel).
* sysdeps/powerpc/fraiseenv.c: Deal with chips that don't have
FE_INVALID_SOFTWARE implemented. Use macros for bit names for clarity.
* sysdeps/powerpc/fsetexcptflag.c: Likewise.
* io/ftw.c: Don't compare holes in structures.
* sysdeps/unix/sysv/linux/sys/sysmacros.h: Cast the result of the
macros to `int', because otherwise it might be `long long' which
the calling code is probably not expecting.
* sysdeps/libm-ieee754/s_lround.c [NO_LONG_DOUBLE]: Fix a few bugs,
document the existence of some more.
* sysdeps/powerpc/s_llrint.c: New file.
* sysdeps/powerpc/s_lrint.c: New file.
* sysdeps/powerpc/s_llround.c: New file.
* sysdeps/powerpc/s_lround.c: New file.
* sysdeps/powerpc/s_sqrt.c: New file.
* sysdeps/powerpc/s_sqrtf.c: New file.
* sysdeps/powerpc/w_sqrt.s: New empty file.
* sysdeps/powerpc/w_sqrtf.s: New empty file.
* sysdeps/powerpc/t_sqrt.c: New file.
* sysdeps/powerpc/test-arithf.c: New file.
* sysdeps/powerpc/Makefile [subdir=math]: Add t_sqrt to support
routines. Add test-arithf to test programs.
* sysdeps/powerpc/bits/mathdef.h: Add FP_ILOGB0, FP_ILOGBNAN.
* sysdeps/powerpc/strcmp.s: Simplify drastically. Now much neater,
and possibly faster (or possibly slower, depending on input).
1997-06-08 22:55 Geoff Keating <geoffk@ozemail.com.au>
* sysdeps/powerpc/fenvbits.h: Correct FE_DFL_ENV and FE_NOMASK_ENV
macros.
* sysdeps/powerpc/s_rint.c: New file.
1997-05-22 08:47 Geoff Keating <geoffk@ozemail.com.au>
* sysdeps/powerpc/Makefile [subdir=math]: Add q_* routines.
* sysdeps/powerpc/Dist: Add quad_float.h.
* sysdeps/powerpc/q_dtoq.c: New file.
* sysdeps/powerpc/q_itoq.c: New file.
* sysdeps/powerpc/q_lltoq.c: New file.
* sysdeps/powerpc/q_neg.c: New file.
* sysdeps/powerpc/q_qtoi.c: New file.
* sysdeps/powerpc/q_qtoll.c: New file.
* sysdeps/powerpc/q_qtos.c: New file.
* sysdeps/powerpc/q_qtou.c: New file.
* sysdeps/powerpc/q_qtoull.c: New file.
* sysdeps/powerpc/q_stoq.c: New file.
* sysdeps/powerpc/q_ulltoq.c: New file.
* sysdeps/powerpc/q_utoq.c: New file.
* sysdeps/powerpc/quad_float.h: New file.
* sysdeps/powerpc/test-arith.c: New file.
* sysdeps/powerpc/fpu_control.h: Fix _FPU_GETCW.
* sysdeps/powerpc/fegetround.c: Use mcrfs to be faster and not
require a stack frame.
* sysdeps/powerpc/bits/fenv.h: Include inline macro for fegetround.
1997-05-18 05:55 Geoff Keating <geoffk@ozemail.com.au>
* sysdeps/powerpc/fenv_libc.h (fegetenv_register,
fesetenv_register): Add 'volatile'.
(set_fpscr_bit, reset_fpscr_bit): New macros, FPSCR_*
constants to use with them.
* sysdeps/powerpc/s_copysign.S: New file.
* sysdeps/powerpc/s_copysignf.s: New file.
* sysdeps/powerpc/s_fabs.S: New file.
* sysdeps/powerpc/s_fabsf.s: New file.
* sysdeps/powerpc/s_isnan.c: New file.
* sysdeps/powerpc/s_isnanf.s: New file.
* sysdeps/powerpc/s_rintf.c: New file.
* sysdeps/powerpc/fenvbits.h: Make FE_INVALID the summary
bit in the FPSCR, not the enable bit.
* sysdeps/powerpc/fraiseexcpt.c: Consequent change to the above.
* sysdeps/powerpc/fclrexcpt.c: Correct.
* sysdeps/powerpc/fsetexcptflag.c: Correct.
* sysdeps/powerpc/ftestexcpt.c: Is now much simpler.
* sysdeps/powerpc/fgetexcptflg.c: Simplify.
* sysdeps/powerpc/strlen.s: Schedule better, save 3 clocks :-).
* sysdeps/powerpc/dl-machine.h (elf_machine_rela): Add comment
explaining some reentrancy issues with lazy PLT entries.
1997-08-09 13:04 Mark Kettenis <kettenis@phys.uva.nl>
* login/logout.c (logout): utmpname returns -1 on error.
* login/libutil.map: Remove updwtmp.
* login/getutline.c: Rename getutline to __getutline and make
getutline a weak alias. Make getutxline a weak alias for
__getutline.
* login/getutid.c: Rename getutid to __getutid and make getutid a
weak alias. Make getutxid a weak alias for __getutid.
* libc.map: Add getutxid, getutxline.
* login/utmpname.c (__utmpname): Reset backend right after backend
endutent call.
* login/utmp_file.c: Reordered functions. Remove unecessary
header files.
(getutent_r_file, pututline_file): Do not call setutent_file. At this
point the file is guaranteed to be open (assert!).
(getutid_r_file, getutline_r_file): Remove check for validity of file
descriptor. At this point the file is guaranteed to be open.
(getutent_r_file, internal_getut_r, getutline_r_file, pututline_file,
updwtmp_file): Do not wait when unlocking file.
* login/utmp_daemon.c: General cleanup and a bit of reordering.
(getutent_r_daemon, pututline_daemon): Do not call setutent_daemon.
At this point the socket is guaranteed to be open (assert!).
(getutid_r_daemon, getutline_r_daemon): Do not check if daemon_sock is
valid. At this point the socket is guaranteed to be open (assert!).
* login/getutline_r.c: Remove unnecessary header files.
(__getutline_r): Do not call backend setutent.
* login/getutid_r.c: Remove unnecessary header files.
(__getutid_r): Do not call backend setutent.
* login/getutent_r.c: Remove unneccesary header files.
(__libc_utmp_unknown_functions): Added getutid_r_unknown,
getutline_r_unknown.
(setutent_unknown): Only set file backend if setutent for the file
backend was successful.
(getutent_r_unknown, pututline_unknown): Call setutent_unknown instead
of __setutent. Report failure if no backend was selected.
(getutid_r_unknown): New function.
(getutline_r_unknown): New function.
(__endutent): Reset backend. This makes sure all backends are checked
on the next setutent call.
1997-08-08 20:20 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
* nis_cache.c: Replace dummy functions.
* libc.map: Add xdr_sizeof symbol.
* sunrpc/Makefile: Add xdr_sizeof to routines.
* sunrpc/rpc/xdr.h: Add xdr_sizeof prototype.
* sunrpc/xdr_sizeof.c: New, from tirpc 2.3.
1997-08-08 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* sysdeps/mach/bits/libc-lock.h (__libc_once): Define correctly.
1997-08-07 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* sysdeps/mach/hurd/profil.c (fetch_samples): Put parens in the
right place.
1997-08-06 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* sysdeps/mach/hurd/profil.c (fetch_samples): Do arithmetic on
PC's in long long to avoid overflow.
1997-08-07 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* sysdeps/mach/bits/libc-lock.h (__libc_once, __libc_once_define):
New macros.
1997-08-06 Andreas Jaeger <aj@arthur.rhein-neckar.de>
* nis/Makefile (headers): Remove bits/nislib.h.
1997-08-06 14:54 Ulrich Drepper <drepper@cygnus.com>
* sysdeps/mach/hurd/Subdirs: Add login.
1997-08-06 14:23 Klaus Espenlaub <kespenla@hydra.informatik.uni-ulm.de>
* db/hash/hash.c (init_hash): Don't use stat() if it doesn't provide
the preferred block size.
* login/programs/database.c (store_state_entry): Don't compile if
there is no ut_type field.
(store_state_entry, store_process_entry): Use the ut_tv field
for timestamps if supported.
* login/programs/utmpdump.c (print_entry): Always use ut_tv field.
* login/programs/xtmp.c: Fix numerous xtmp/utmp typos. Use the ut_tv
field for timestamps if supported.
* login/programs/xtmp.h: Fix xtmp/utmp typo.
* sysdeps/posix/defs.c (stdstream): Change (PTR) to (void *).
* sysdeps/stub/connect.c (connect): Change to __connect, add alias.
* sysdeps/stub/send.c (send): Likewise.
* sysdeps/stub/s_exp2f.c: Emit correct stub_warning().
* sysdeps/stub/statfs.c: Move stub_warning() to the usual place.
* sysdeps/stub/init-first.c: Add definition of __libc_pid.
1997-08-05 13:28 Philip Blundell <pb@spring.nexus.co.uk>
* sysdeps/standalone/arm/bits/errno.h: Add EISDIR, EOPNOTSUPP;
tidy up formatting.
* Makefile (subdirs): Remove `login'.
* sysdeps/unix/Subdirs: New file; build `login' subdirectory
for Unix systems.
1997-08-05 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* sysdeps/generic/bits/utmpx.h: New file.
* sysdeps/mach/hurd/Dist: Add some files.
* sysdeps/mips/Dist: Likewise.
* sysdeps/mips/mips64/Dist: Likewise.
* sysdeps/sparc/Dist: Likewise.
* sysdeps/unix/sysv/linux/mips/Dist: Likewise.
* sysdeps/unix/sysv/linux/sparc/Dist: Likewise.
* sysdeps/mips/mipsel/Dist: New file.
* sysdeps/sparc64/elf/Dist: New file.
* sysdeps/unix/sysv/linux/sparc64/Dist: New file.
1997-08-05 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
* libc.map: Add missing symbols.
1997-08-05 Andreas Jaeger <aj@arthur.rhein-neckar.de>
* manual/socket.texi: Correct typos.
* manual/math.texi: Correct typos.
* manual/time.texi (Formatting Date and Time): Likewise.
1997-08-04 13:06 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* gmon/gmon.c (write_gmon): New function; guts from _mcleanup.
(_mcleanup): Use write_gmon.
(write_profiling): This function can be safely called at any time
to write a current histogram without interfering with ongoing
profiling.
* sysdeps/mach/hurd/profil.c (fetch_samples): Initialize NSAMPLES.
1997-08-01 17:53 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* sysdeps/mach/hurd/profil.c (fetch_samples): Sample buffer need
not be vm_deallocated; it's a stack buffer.
(profil_vm_deallocate): Delete prototype.
(#include <../mach/RPC_vm_deallocate_rpc.c>): Drop this
inclusion.
* sysdeps/mach/hurd/Makefile
($(common-objpfx)hurd/../mach/RPC_vm_deallocate_rpc.c): Delete
this rule.
* sysdeps/mach/hurd/profil.c (fetch_samples): New function, guts
from profile_waiter.
(profile_waiter): Use fetch_samples.
(profil): When turning off profiling, fetch the last bunch of
samples before disabling PC sampling.
(fetch_samples): Add prototype.
1997-07-30 12:53 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* sysdeps/mach/hurd/Makefile: Give normal rules for the mach RPC
source included by profil.c instead of trying to use
before-compile grot.
1997-07-23 15:04 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
* sysdeps/mach/hurd/profil.c (profile_waiter): Do vm_deallocate
after releasing lock. Use special RPC stubs and avoid assert,
thus making this function entirely independent of the threadvar
mechanism and of cthreads.
(lock): Convert to be a spin lock instead of a mutex, so that the
waiter thread need not use cthreads. Use a fork prepare hook
instead of _hurd_fork_locks to make sure we are clean before
forking.
(fork_profil_child): Renamed from fork_profil.
(profil_reply_port): New variable.
(profil_vm_deallocate, profil_task_get_sampled_pcs): Special RPC
stubs made by special hacks.
* sysdeps/mach/hurd/Makefile (before-compile): Add the mach RPC
source files that profil.c needs if we are in the gmon directory.
* mach/setup-thread.c (__mach_setup_thread): Delete avoidance of a
cthreads bug that hasn't existed for two years.
* stdio-common/printf_fp.c (__printf_fp): Correct rounding of numbers
* locale/programs/locale.c (print_escaped): New function.
* time/australasia: Likewise.
(open_database, synchronize_database, initialize_database):
* nss/nss_files/files-netgrp.c (_nss_netgroup_parseline): Don't
* Makerules (load-map-file): Currectly handle missing map file.
cannot rely on M_SQRT2 being defined.
(log1p): Use __M_SQRT2 not M_SQRT2.
1997-08-10 18:37:15 +00:00
|
|
|
{
|
|
|
|
printf ("Test: not testing FE_NOMASK_ENV, it isn't implemented.\n");
|
|
|
|
return;
|
|
|
|
}
|
1997-07-06 22:02:42 +00:00
|
|
|
|
2023-11-02 14:15:55 +00:00
|
|
|
printf ("Test: after %s (FE_NOMASK_ENV) processes will abort\n", funcname (func));
|
1997-07-06 22:02:42 +00:00
|
|
|
printf (" when feraiseexcept (%s) is called.\n", flag_name);
|
1998-02-26 11:20:59 +00:00
|
|
|
pid = fork ();
|
1997-07-06 22:02:42 +00:00
|
|
|
if (pid == 0)
|
|
|
|
{
|
2014-12-30 19:11:13 +00:00
|
|
|
# ifdef RLIMIT_CORE
|
1998-01-21 17:04:36 +00:00
|
|
|
/* Try to avoid dumping core. */
|
|
|
|
struct rlimit core_limit;
|
|
|
|
core_limit.rlim_cur = 0;
|
|
|
|
core_limit.rlim_max = 0;
|
|
|
|
setrlimit (RLIMIT_CORE, &core_limit);
|
2014-12-30 19:11:13 +00:00
|
|
|
# endif
|
1998-01-21 17:04:36 +00:00
|
|
|
|
1997-07-11 01:19:07 +00:00
|
|
|
fesetenv (FE_NOMASK_ENV);
|
1997-07-06 22:02:42 +00:00
|
|
|
feraiseexcept (fe_exc);
|
|
|
|
exit (2);
|
|
|
|
}
|
|
|
|
else if (pid < 0)
|
|
|
|
{
|
|
|
|
if (errno != ENOSYS)
|
|
|
|
{
|
|
|
|
printf (" Fail: Could not fork.\n");
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
printf (" `fork' not implemented, test ignored.\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (waitpid (pid, &status, 0) != pid)
|
|
|
|
{
|
|
|
|
printf (" Fail: waitpid call failed.\n");
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
else if (WIFSIGNALED (status) && WTERMSIG (status) == SIGFPE)
|
|
|
|
printf (" Pass: Process received SIGFPE.\n");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf (" Fail: Process didn't receive signal and exited with status %d.\n",
|
|
|
|
status);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
}
|
2014-12-30 19:11:13 +00:00
|
|
|
# endif
|
1997-07-06 22:02:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Test that program doesn't abort with default environment */
|
|
|
|
static void
|
2023-11-02 14:15:55 +00:00
|
|
|
feenv_mask_test (const char *flag_name, int fe_exc, int (*func)(const fenv_t *))
|
1997-07-06 22:02:42 +00:00
|
|
|
{
|
|
|
|
int status;
|
|
|
|
pid_t pid;
|
|
|
|
|
2023-11-02 14:15:55 +00:00
|
|
|
printf ("Test: after %s (FE_DFL_ENV) processes will not abort\n", funcname (func));
|
1997-07-06 22:02:42 +00:00
|
|
|
printf (" when feraiseexcept (%s) is called.\n", flag_name);
|
|
|
|
pid = fork ();
|
|
|
|
if (pid == 0)
|
|
|
|
{
|
1998-01-21 17:04:36 +00:00
|
|
|
#ifdef RLIMIT_CORE
|
|
|
|
/* Try to avoid dumping core. */
|
|
|
|
struct rlimit core_limit;
|
|
|
|
core_limit.rlim_cur = 0;
|
|
|
|
core_limit.rlim_max = 0;
|
|
|
|
setrlimit (RLIMIT_CORE, &core_limit);
|
|
|
|
#endif
|
|
|
|
|
2023-11-02 14:15:55 +00:00
|
|
|
func (FE_DFL_ENV);
|
1997-07-06 22:02:42 +00:00
|
|
|
feraiseexcept (fe_exc);
|
|
|
|
exit (2);
|
|
|
|
}
|
|
|
|
else if (pid < 0)
|
|
|
|
{
|
|
|
|
if (errno != ENOSYS)
|
|
|
|
{
|
|
|
|
printf (" Fail: Could not fork.\n");
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
printf (" `fork' not implemented, test ignored.\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (waitpid (pid, &status, 0) != pid)
|
|
|
|
{
|
|
|
|
printf (" Fail: waitpid call failed.\n");
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
else if (WIFEXITED (status) && WEXITSTATUS (status) == 2)
|
|
|
|
printf (" Pass: Process exited normally.\n");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf (" Fail: Process exited abnormally with status %d.\n",
|
|
|
|
status);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-08-19 16:58:09 +00:00
|
|
|
/* Test that program aborts with no masked interrupts */
|
|
|
|
static void
|
|
|
|
feexcp_nomask_test (const char *flag_name, int fe_exc)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
pid_t pid;
|
1997-07-06 22:02:42 +00:00
|
|
|
|
2014-04-17 08:39:27 +00:00
|
|
|
if (!EXCEPTION_ENABLE_SUPPORTED (fe_exc) && feenableexcept (fe_exc) == -1)
|
|
|
|
{
|
|
|
|
printf ("Test: not testing feenableexcept, it isn't implemented.\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf ("Test: after feenableexcept (%s) processes will abort\n",
|
2003-05-22 02:09:54 +00:00
|
|
|
flag_name);
|
2000-08-19 18:29:19 +00:00
|
|
|
printf (" when feraiseexcept (%s) is called.\n", flag_name);
|
2000-08-19 16:58:09 +00:00
|
|
|
pid = fork ();
|
|
|
|
if (pid == 0)
|
|
|
|
{
|
|
|
|
#ifdef RLIMIT_CORE
|
|
|
|
/* Try to avoid dumping core. */
|
|
|
|
struct rlimit core_limit;
|
|
|
|
core_limit.rlim_cur = 0;
|
|
|
|
core_limit.rlim_max = 0;
|
|
|
|
setrlimit (RLIMIT_CORE, &core_limit);
|
|
|
|
#endif
|
1997-07-06 22:02:42 +00:00
|
|
|
|
2000-08-19 16:58:09 +00:00
|
|
|
fedisableexcept (FE_ALL_EXCEPT);
|
|
|
|
feenableexcept (fe_exc);
|
|
|
|
feraiseexcept (fe_exc);
|
|
|
|
exit (2);
|
|
|
|
}
|
|
|
|
else if (pid < 0)
|
|
|
|
{
|
|
|
|
if (errno != ENOSYS)
|
|
|
|
{
|
|
|
|
printf (" Fail: Could not fork.\n");
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
printf (" `fork' not implemented, test ignored.\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (waitpid (pid, &status, 0) != pid)
|
|
|
|
{
|
|
|
|
printf (" Fail: waitpid call failed.\n");
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
else if (WIFSIGNALED (status) && WTERMSIG (status) == SIGFPE)
|
|
|
|
printf (" Pass: Process received SIGFPE.\n");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf (" Fail: Process didn't receive signal and exited with status %d.\n",
|
|
|
|
status);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Test that program doesn't abort with exception. */
|
1997-07-06 22:02:42 +00:00
|
|
|
static void
|
2000-08-19 16:58:09 +00:00
|
|
|
feexcp_mask_test (const char *flag_name, int fe_exc)
|
1997-07-06 22:02:42 +00:00
|
|
|
{
|
2000-08-19 16:58:09 +00:00
|
|
|
int status;
|
2000-09-28 23:11:33 +00:00
|
|
|
int exception;
|
2000-08-19 16:58:09 +00:00
|
|
|
pid_t pid;
|
1997-07-06 22:02:42 +00:00
|
|
|
|
2003-05-22 02:09:54 +00:00
|
|
|
printf ("Test: after fedisableexcept (%s) processes will not abort\n",
|
|
|
|
flag_name);
|
2000-08-19 18:29:19 +00:00
|
|
|
printf (" when feraiseexcept (%s) is called.\n", flag_name);
|
2000-08-19 16:58:09 +00:00
|
|
|
pid = fork ();
|
|
|
|
if (pid == 0)
|
|
|
|
{
|
|
|
|
#ifdef RLIMIT_CORE
|
|
|
|
/* Try to avoid dumping core. */
|
|
|
|
struct rlimit core_limit;
|
|
|
|
core_limit.rlim_cur = 0;
|
|
|
|
core_limit.rlim_max = 0;
|
|
|
|
setrlimit (RLIMIT_CORE, &core_limit);
|
|
|
|
#endif
|
|
|
|
feenableexcept (FE_ALL_EXCEPT);
|
2000-09-28 23:11:33 +00:00
|
|
|
exception = fe_exc;
|
|
|
|
#ifdef FE_INEXACT
|
|
|
|
/* The standard allows the inexact exception to be set together with the
|
|
|
|
underflow and overflow exceptions. So add FE_INEXACT to the set of
|
|
|
|
exceptions to be disabled if we will be raising underflow or
|
|
|
|
overflow. */
|
|
|
|
# ifdef FE_OVERFLOW
|
|
|
|
if (fe_exc & FE_OVERFLOW)
|
|
|
|
exception |= FE_INEXACT;
|
|
|
|
# endif
|
|
|
|
# ifdef FE_UNDERFLOW
|
|
|
|
if (fe_exc & FE_UNDERFLOW)
|
|
|
|
exception |= FE_INEXACT;
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
fedisableexcept (exception);
|
2000-08-19 16:58:09 +00:00
|
|
|
feraiseexcept (fe_exc);
|
|
|
|
exit (2);
|
|
|
|
}
|
|
|
|
else if (pid < 0)
|
|
|
|
{
|
|
|
|
if (errno != ENOSYS)
|
|
|
|
{
|
|
|
|
printf (" Fail: Could not fork.\n");
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
printf (" `fork' not implemented, test ignored.\n");
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (waitpid (pid, &status, 0) != pid)
|
|
|
|
{
|
|
|
|
printf (" Fail: waitpid call failed.\n");
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
else if (WIFEXITED (status) && WEXITSTATUS (status) == 2)
|
|
|
|
printf (" Pass: Process exited normally.\n");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
printf (" Fail: Process exited abnormally with status %d.\n",
|
|
|
|
status);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Tests for feenableexcept/fedisableexcept/fegetexcept. */
|
|
|
|
static void
|
|
|
|
feenable_test (const char *flag_name, int fe_exc)
|
|
|
|
{
|
|
|
|
int excepts;
|
|
|
|
|
|
|
|
printf ("Tests for feenableexcepts etc. with flag %s\n", flag_name);
|
|
|
|
|
|
|
|
/* First disable all exceptions. */
|
|
|
|
if (fedisableexcept (FE_ALL_EXCEPT) == -1)
|
|
|
|
{
|
|
|
|
printf ("Test: fedisableexcept (FE_ALL_EXCEPT) failed\n");
|
|
|
|
++count_errors;
|
|
|
|
/* If this fails, the other tests don't make sense. */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
excepts = fegetexcept ();
|
|
|
|
if (excepts != 0)
|
|
|
|
{
|
|
|
|
printf ("Test: fegetexcept (%s) failed, return should be 0, is %d\n",
|
|
|
|
flag_name, excepts);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
excepts = feenableexcept (fe_exc);
|
2014-04-17 08:39:27 +00:00
|
|
|
if (!EXCEPTION_ENABLE_SUPPORTED (fe_exc) && excepts == -1)
|
|
|
|
{
|
|
|
|
printf ("Test: not testing feenableexcept, it isn't implemented.\n");
|
|
|
|
return;
|
|
|
|
}
|
2000-08-19 16:58:09 +00:00
|
|
|
if (excepts == -1)
|
|
|
|
{
|
|
|
|
printf ("Test: feenableexcept (%s) failed\n", flag_name);
|
|
|
|
++count_errors;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (excepts != 0)
|
|
|
|
{
|
|
|
|
printf ("Test: feenableexcept (%s) failed, return should be 0, is %x\n",
|
|
|
|
flag_name, excepts);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
excepts = fegetexcept ();
|
|
|
|
if (excepts != fe_exc)
|
|
|
|
{
|
|
|
|
printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
|
|
|
|
flag_name, fe_exc, excepts);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* And now disable the exception again. */
|
|
|
|
excepts = fedisableexcept (fe_exc);
|
|
|
|
if (excepts == -1)
|
|
|
|
{
|
|
|
|
printf ("Test: fedisableexcept (%s) failed\n", flag_name);
|
|
|
|
++count_errors;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (excepts != fe_exc)
|
|
|
|
{
|
|
|
|
printf ("Test: fedisableexcept (%s) failed, return should be 0x%x, is 0x%x\n",
|
|
|
|
flag_name, fe_exc, excepts);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
excepts = fegetexcept ();
|
|
|
|
if (excepts != 0)
|
|
|
|
{
|
|
|
|
printf ("Test: fegetexcept (%s) failed, return should be 0, is 0x%x\n",
|
|
|
|
flag_name, excepts);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now the other way round: Enable all exceptions and disable just this one. */
|
|
|
|
if (feenableexcept (FE_ALL_EXCEPT) == -1)
|
|
|
|
{
|
|
|
|
printf ("Test: feenableexcept (FE_ALL_EXCEPT) failed\n");
|
|
|
|
++count_errors;
|
|
|
|
/* If this fails, the other tests don't make sense. */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
excepts = fegetexcept ();
|
|
|
|
if (excepts != FE_ALL_EXCEPT)
|
|
|
|
{
|
|
|
|
printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
|
|
|
|
flag_name, FE_ALL_EXCEPT, excepts);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
excepts = fedisableexcept (fe_exc);
|
|
|
|
if (excepts == -1)
|
|
|
|
{
|
|
|
|
printf ("Test: fedisableexcept (%s) failed\n", flag_name);
|
|
|
|
++count_errors;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (excepts != FE_ALL_EXCEPT)
|
|
|
|
{
|
|
|
|
printf ("Test: fedisableexcept (%s) failed, return should be 0, is 0x%x\n",
|
|
|
|
flag_name, excepts);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
excepts = fegetexcept ();
|
|
|
|
if (excepts != (FE_ALL_EXCEPT & ~fe_exc))
|
|
|
|
{
|
|
|
|
printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
|
|
|
|
flag_name, (FE_ALL_EXCEPT & ~fe_exc), excepts);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* And now enable the exception again. */
|
|
|
|
excepts = feenableexcept (fe_exc);
|
|
|
|
if (excepts == -1)
|
|
|
|
{
|
|
|
|
printf ("Test: feenableexcept (%s) failed\n", flag_name);
|
|
|
|
++count_errors;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (excepts != (FE_ALL_EXCEPT & ~fe_exc))
|
|
|
|
{
|
|
|
|
printf ("Test: feenableexcept (%s) failed, return should be 0, is 0x%x\n",
|
|
|
|
flag_name, excepts);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
excepts = fegetexcept ();
|
|
|
|
if (excepts != FE_ALL_EXCEPT)
|
|
|
|
{
|
|
|
|
printf ("Test: fegetexcept (%s) failed, return should be 0x%x, is 0x%x\n",
|
|
|
|
flag_name, FE_ALL_EXCEPT, excepts);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
feexcp_nomask_test (flag_name, fe_exc);
|
|
|
|
feexcp_mask_test (flag_name, fe_exc);
|
2000-08-19 18:29:19 +00:00
|
|
|
|
2000-08-19 16:58:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
fe_single_test (const char *flag_name, int fe_exc)
|
|
|
|
{
|
2023-11-02 14:15:55 +00:00
|
|
|
feenv_nomask_test (flag_name, fe_exc, fesetenv);
|
|
|
|
feenv_mask_test (flag_name, fe_exc, fesetenv);
|
2000-08-19 16:58:09 +00:00
|
|
|
feenable_test (flag_name, fe_exc);
|
|
|
|
}
|
2023-11-02 14:15:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
feupdate_single_test (const char *flag_name, int fe_exc)
|
|
|
|
{
|
|
|
|
feenv_nomask_test (flag_name, fe_exc, feupdateenv);
|
|
|
|
feenv_mask_test (flag_name, fe_exc, feupdateenv);
|
|
|
|
}
|
2014-12-30 19:11:13 +00:00
|
|
|
#endif
|
2000-08-19 16:58:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
feenv_tests (void)
|
|
|
|
{
|
2000-08-19 18:29:19 +00:00
|
|
|
/* We might have some exceptions still set. */
|
|
|
|
feclearexcept (FE_ALL_EXCEPT);
|
|
|
|
|
1997-07-06 22:02:42 +00:00
|
|
|
#ifdef FE_DIVBYZERO
|
2000-08-19 16:58:09 +00:00
|
|
|
fe_single_test ("FE_DIVBYZERO", FE_DIVBYZERO);
|
1997-07-06 22:02:42 +00:00
|
|
|
#endif
|
|
|
|
#ifdef FE_INVALID
|
2000-08-19 16:58:09 +00:00
|
|
|
fe_single_test ("FE_INVALID", FE_INVALID);
|
1997-07-06 22:02:42 +00:00
|
|
|
#endif
|
|
|
|
#ifdef FE_INEXACT
|
2000-08-19 16:58:09 +00:00
|
|
|
fe_single_test ("FE_INEXACT", FE_INEXACT);
|
1997-07-06 22:02:42 +00:00
|
|
|
#endif
|
|
|
|
#ifdef FE_UNDERFLOW
|
2000-08-19 16:58:09 +00:00
|
|
|
fe_single_test ("FE_UNDERFLOW", FE_UNDERFLOW);
|
1997-07-06 22:02:42 +00:00
|
|
|
#endif
|
|
|
|
#ifdef FE_OVERFLOW
|
2000-08-19 16:58:09 +00:00
|
|
|
fe_single_test ("FE_OVERFLOW", FE_OVERFLOW);
|
1997-07-06 22:02:42 +00:00
|
|
|
#endif
|
|
|
|
fesetenv (FE_DFL_ENV);
|
|
|
|
}
|
|
|
|
|
2023-11-02 14:15:55 +00:00
|
|
|
#if FE_ALL_EXCEPT
|
|
|
|
static void
|
|
|
|
feupdateenv_single_test (const char *test_name, int fe_exc, int exception)
|
|
|
|
{
|
|
|
|
char str[100];
|
|
|
|
fenv_t env;
|
|
|
|
int res;
|
|
|
|
|
|
|
|
snprintf (str, sizeof str, "feupdateenv %s and FL_DFL_ENV", test_name);
|
|
|
|
update_single_exc (str, FE_DFL_ENV, fe_exc, NO_EXC, exception);
|
|
|
|
|
|
|
|
feraiseexcept (FE_ALL_EXCEPT);
|
|
|
|
res = fegetenv (&env);
|
|
|
|
if (res != 0)
|
|
|
|
{
|
|
|
|
printf ("fegetenv failed: %d\n", res);
|
|
|
|
++count_errors;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
snprintf (str, sizeof str, "feupdateenv %s and FE_ALL_EXCEPT", test_name);
|
|
|
|
update_single_exc (str, &env, ALL_EXC, ALL_EXC, exception);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void
|
|
|
|
feupdateenv_tests (void)
|
|
|
|
{
|
|
|
|
/* We might have some exceptions still set. */
|
|
|
|
feclearexcept (FE_ALL_EXCEPT);
|
|
|
|
|
|
|
|
#ifdef FE_DIVBYZERO
|
|
|
|
feupdate_single_test ("FE_DIVBYZERO", FE_DIVBYZERO);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_INVALID
|
|
|
|
feupdate_single_test ("FE_INVALID", FE_INVALID);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_INEXACT
|
|
|
|
feupdate_single_test ("FE_INEXACT", FE_INEXACT);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_UNDERFLOW
|
|
|
|
feupdate_single_test ("FE_UNDERFLOW", FE_UNDERFLOW);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_OVERFLOW
|
|
|
|
feupdate_single_test ("FE_OVERFLOW", FE_OVERFLOW);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef FE_DIVBYZERO
|
|
|
|
feupdateenv_single_test ("DIVBYZERO", DIVBYZERO_EXC, FE_DIVBYZERO);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_INVALID
|
|
|
|
feupdateenv_single_test ("INVALID", INVALID_EXC, FE_INVALID);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_INEXACT
|
|
|
|
feupdateenv_single_test ("INEXACT", INEXACT_EXC, FE_INEXACT);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_UNDERFLOW
|
|
|
|
feupdateenv_single_test ("UNDERFLOW", UNDERFLOW_EXC, FE_UNDERFLOW);
|
|
|
|
#endif
|
|
|
|
#ifdef FE_OVERFLOW
|
|
|
|
feupdateenv_single_test ("OVERFLOW", OVERFLOW_EXC, FE_OVERFLOW);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
feupdateenv (FE_DFL_ENV);
|
|
|
|
}
|
|
|
|
|
1997-07-06 22:02:42 +00:00
|
|
|
|
2007-04-16 20:15:57 +00:00
|
|
|
static void
|
|
|
|
feholdexcept_tests (void)
|
|
|
|
{
|
|
|
|
fenv_t saved, saved2;
|
|
|
|
int res;
|
|
|
|
|
|
|
|
feclearexcept (FE_ALL_EXCEPT);
|
|
|
|
fedisableexcept (FE_ALL_EXCEPT);
|
|
|
|
#ifdef FE_DIVBYZERO
|
|
|
|
feraiseexcept (FE_DIVBYZERO);
|
|
|
|
#endif
|
2017-01-09 18:27:49 +00:00
|
|
|
if (EXCEPTION_TESTS (float))
|
|
|
|
test_exceptions ("feholdexcept_tests FE_DIVBYZERO test",
|
|
|
|
DIVBYZERO_EXC, 0);
|
2007-04-16 20:15:57 +00:00
|
|
|
res = feholdexcept (&saved);
|
|
|
|
if (res != 0)
|
|
|
|
{
|
|
|
|
printf ("feholdexcept failed: %d\n", res);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
#if defined FE_TONEAREST && defined FE_TOWARDZERO
|
|
|
|
res = fesetround (FE_TOWARDZERO);
|
2017-01-09 18:27:49 +00:00
|
|
|
if (res != 0 && ROUNDING_TESTS (float, FE_TOWARDZERO))
|
2007-04-16 20:15:57 +00:00
|
|
|
{
|
|
|
|
printf ("fesetround failed: %d\n", res);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
test_exceptions ("feholdexcept_tests 0 test", NO_EXC, 0);
|
2012-05-17 12:49:19 +00:00
|
|
|
#ifdef FE_INVALID
|
2007-04-16 20:15:57 +00:00
|
|
|
feraiseexcept (FE_INVALID);
|
2017-01-09 18:27:49 +00:00
|
|
|
if (EXCEPTION_TESTS (float))
|
|
|
|
test_exceptions ("feholdexcept_tests FE_INVALID test",
|
|
|
|
INVALID_EXC, 0);
|
2012-05-17 12:49:19 +00:00
|
|
|
#endif
|
2007-04-16 20:15:57 +00:00
|
|
|
res = feupdateenv (&saved);
|
|
|
|
if (res != 0)
|
|
|
|
{
|
|
|
|
printf ("feupdateenv failed: %d\n", res);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
#if defined FE_TONEAREST && defined FE_TOWARDZERO
|
|
|
|
res = fegetround ();
|
|
|
|
if (res != FE_TONEAREST)
|
|
|
|
{
|
|
|
|
printf ("feupdateenv didn't restore rounding mode: %d\n", res);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
#endif
|
2017-01-09 18:27:49 +00:00
|
|
|
if (EXCEPTION_TESTS (float))
|
|
|
|
test_exceptions ("feholdexcept_tests FE_DIVBYZERO|FE_INVALID test",
|
|
|
|
DIVBYZERO_EXC | INVALID_EXC, 0);
|
2007-04-16 20:15:57 +00:00
|
|
|
feclearexcept (FE_ALL_EXCEPT);
|
2012-05-17 12:49:19 +00:00
|
|
|
#ifdef FE_INVALID
|
2007-04-16 20:15:57 +00:00
|
|
|
feraiseexcept (FE_INVALID);
|
2012-05-17 12:49:19 +00:00
|
|
|
#endif
|
2007-04-16 20:15:57 +00:00
|
|
|
#if defined FE_TONEAREST && defined FE_UPWARD
|
|
|
|
res = fesetround (FE_UPWARD);
|
2017-01-09 18:27:49 +00:00
|
|
|
if (res != 0 && ROUNDING_TESTS (float, FE_UPWARD))
|
2007-04-16 20:15:57 +00:00
|
|
|
{
|
|
|
|
printf ("fesetround failed: %d\n", res);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
res = feholdexcept (&saved2);
|
|
|
|
if (res != 0)
|
|
|
|
{
|
|
|
|
printf ("feholdexcept failed: %d\n", res);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
#if defined FE_TONEAREST && defined FE_UPWARD
|
|
|
|
res = fesetround (FE_TONEAREST);
|
|
|
|
if (res != 0)
|
|
|
|
{
|
|
|
|
printf ("fesetround failed: %d\n", res);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
test_exceptions ("feholdexcept_tests 0 2nd test", NO_EXC, 0);
|
2012-05-17 12:49:19 +00:00
|
|
|
#ifdef FE_INEXACT
|
2007-04-16 20:15:57 +00:00
|
|
|
feraiseexcept (FE_INEXACT);
|
2017-01-09 18:27:49 +00:00
|
|
|
if (EXCEPTION_TESTS (float))
|
|
|
|
test_exceptions ("feholdexcept_tests FE_INEXACT test",
|
|
|
|
INEXACT_EXC, 0);
|
2012-05-17 12:49:19 +00:00
|
|
|
#endif
|
2007-04-16 20:15:57 +00:00
|
|
|
res = feupdateenv (&saved2);
|
|
|
|
if (res != 0)
|
|
|
|
{
|
|
|
|
printf ("feupdateenv failed: %d\n", res);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
#if defined FE_TONEAREST && defined FE_UPWARD
|
|
|
|
res = fegetround ();
|
2017-01-09 18:27:49 +00:00
|
|
|
if (res != FE_UPWARD && ROUNDING_TESTS (float, FE_UPWARD))
|
2007-04-16 20:15:57 +00:00
|
|
|
{
|
|
|
|
printf ("feupdateenv didn't restore rounding mode: %d\n", res);
|
|
|
|
++count_errors;
|
|
|
|
}
|
|
|
|
fesetround (FE_TONEAREST);
|
|
|
|
#endif
|
2017-01-09 18:27:49 +00:00
|
|
|
if (EXCEPTION_TESTS (float))
|
|
|
|
test_exceptions ("feholdexcept_tests FE_INEXACT|FE_INVALID test",
|
|
|
|
INVALID_EXC | INEXACT_EXC, 0);
|
2007-04-16 20:15:57 +00:00
|
|
|
feclearexcept (FE_ALL_EXCEPT);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1999-10-31 23:32:56 +00:00
|
|
|
/* IEC 559 and ISO C99 define a default startup environment */
|
1997-07-06 22:02:42 +00:00
|
|
|
static void
|
|
|
|
initial_tests (void)
|
|
|
|
{
|
|
|
|
test_exceptions ("Initially all exceptions should be cleared",
|
1997-07-24 01:36:01 +00:00
|
|
|
NO_EXC, 0);
|
2001-04-11 05:42:38 +00:00
|
|
|
#ifdef FE_TONEAREST
|
2023-05-20 13:37:47 +00:00
|
|
|
test_rounding ("Rounding direction should be initialized to nearest",
|
1997-07-06 22:02:42 +00:00
|
|
|
FE_TONEAREST);
|
2001-04-11 05:42:38 +00:00
|
|
|
#endif
|
1997-07-06 22:02:42 +00:00
|
|
|
}
|
|
|
|
|
2023-11-02 14:15:55 +00:00
|
|
|
static int
|
|
|
|
do_test (void)
|
1997-06-27 23:09:40 +00:00
|
|
|
{
|
1997-07-06 22:02:42 +00:00
|
|
|
initial_tests ();
|
1997-06-27 23:09:40 +00:00
|
|
|
fe_tests ();
|
1997-07-06 22:02:42 +00:00
|
|
|
feenv_tests ();
|
2007-04-16 20:15:57 +00:00
|
|
|
feholdexcept_tests ();
|
2023-11-02 14:15:55 +00:00
|
|
|
feupdateenv_tests ();
|
1997-06-27 23:09:40 +00:00
|
|
|
|
|
|
|
if (count_errors)
|
|
|
|
{
|
2000-02-22 09:00:35 +00:00
|
|
|
printf ("\n%d errors occurred.\n", count_errors);
|
1997-06-27 23:09:40 +00:00
|
|
|
exit (1);
|
|
|
|
}
|
|
|
|
printf ("\n All tests passed successfully.\n");
|
2000-12-04 08:37:38 +00:00
|
|
|
return 0;
|
1997-06-27 23:09:40 +00:00
|
|
|
}
|
2023-11-02 14:15:55 +00:00
|
|
|
|
|
|
|
#include <support/test-driver.c>
|