Date: Tue, 16 Sep 2003 00:53:29 +0200 (CEST) From: Stefan Farfeleder <stefan@fafoe.narf.at> To: FreeBSD-gnats-submit@FreeBSD.org Cc: stefan@fafoe.narf.at Subject: standards/56906: Several math(3) functions fail to set errno on a domain error Message-ID: <20030915225329.95B30498@frog.fafoe.narf.at> Resent-Message-ID: <200309152300.h8FN0fd0042682@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 56906 >Category: standards >Synopsis: Several math(3) functions fail to set errno on a domain error >Confidential: no >Severity: serious >Priority: low >Responsible: freebsd-standards >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Sep 15 16:00:34 PDT 2003 >Closed-Date: >Last-Modified: >Originator: Stefan Farfeleder >Release: FreeBSD 5.1-CURRENT i386 >Organization: >Environment: System: FreeBSD frog.fafoe.narf.at 5.1-CURRENT FreeBSD 5.1-CURRENT #8: Thu Sep 11 14:09:49 CEST 2003 freebsd@frog.fafoe.narf.at:/freebsd/frog/obj/freebsd/frog/src/sys/FROG i386 >Description: ISO C90 says that errno must be set to EDOM if a domain error occurs. The cases where a domain error definitely has to occur are: acos(x) if |x| > 1, asin(x) if |x| > 1, log(x) if x < 0, log10(x) if x < 0, sqrt(x) if x < 0 and pow(x, y) if x < 0 && y not an integer or if x == 0 && y <= 0. FreeBSD's libm fails to set errno on each of these cases even though the man pages of acos, asin and sqrt claim conformance to C89/90. >How-To-Repeat: This program should set errno to EDOM seven times but it currently only prints zeroes. %% #include <errno.h> #include <math.h> #include <stdio.h> #define TEST1(func, arg) { func, arg, #func } #define TEST2(func, arg1, arg2) { func, arg1, arg2, #func } struct { double (*func)(double); double arg; char *name; } test1[] = { TEST1(acos, 2), TEST1(asin, 2), TEST1(log, -1), TEST1(log10, -1), TEST1(sqrt, -1), }; struct { double (*func)(double, double); double arg1; double arg2; char *name; } test2[] = { TEST2(pow, -1, 0.5), TEST2(pow, 0, -1), }; int main(void) { int i; for (i = 0; i < sizeof(test1) / sizeof(*test1); i++) { errno = 0; test1[i].func(test1[i].arg); printf("%s(%f): errno = %d\n", test1[i].name, test1[i].arg, errno); } for (i = 0; i < sizeof(test2) / sizeof(*test2); i++) { errno = 0; test2[i].func(test2[i].arg1, test2[i].arg2); printf("%s(%f, %f): errno = %d\n", test2[i].name, test2[i].arg1, test2[i].arg2, errno); } return (0); } %% >Fix: Compiling msun with -D_POSIX_MODE fixes the setting of errno. I have no idea if this breaks other parts of libm though; there don't seem to be any regression tests for libm. --- msun-Makefile.diff begins here --- Index: src/lib/msun/Makefile =================================================================== RCS file: /usr/home/ncvs/src/lib/msun/Makefile,v retrieving revision 1.35 diff -u -r1.35 Makefile --- src/lib/msun/Makefile 17 Aug 2003 08:28:46 -0000 1.35 +++ src/lib/msun/Makefile 15 Sep 2003 21:50:12 -0000 @@ -63,7 +63,7 @@ .PATH: ${.CURDIR}/man .PATH: ${.CURDIR}/src -CFLAGS+= -D_IEEE_LIBM +CFLAGS+= -D_POSIX_MODE LIB= m SHLIBDIR?= /lib --- msun-Makefile.diff ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030915225329.95B30498>