From owner-freebsd-standards@FreeBSD.ORG Mon Sep 15 18:44:43 2003 Return-Path: Delivered-To: freebsd-standards@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4A1AB16A4B3; Mon, 15 Sep 2003 18:44:43 -0700 (PDT) Received: from mailman.zeta.org.au (mailman.zeta.org.au [203.26.10.16]) by mx1.FreeBSD.org (Postfix) with ESMTP id 92ACA43FAF; Mon, 15 Sep 2003 18:44:16 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: from gamplex.bde.org (katana.zip.com.au [61.8.7.246]) by mailman.zeta.org.au (8.9.3p2/8.8.7) with ESMTP id LAA18113; Tue, 16 Sep 2003 11:44:06 +1000 Date: Tue, 16 Sep 2003 11:42:44 +1000 (EST) From: Bruce Evans X-X-Sender: bde@gamplex.bde.org To: Stefan Farfeleder In-Reply-To: <20030915225329.95B30498@frog.fafoe.narf.at> Message-ID: <20030916104414.H2924@gamplex.bde.org> References: <20030915225329.95B30498@frog.fafoe.narf.at> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII cc: FreeBSD-gnats-submit@freebsd.org cc: freebsd-standards@freebsd.org Subject: Re: standards/56906: Several math(3) functions fail to set errno on a domain error X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Sep 2003 01:44:43 -0000 On Tue, 16 Sep 2003, Stefan Farfeleder wrote: > >Synopsis: Several math(3) functions fail to set errno on a domain error This is intentional. > >Description: > ISO C90 says that errno must be set to EDOM if a domain error occurs. As you probably know, C99 doesn't require this. FreeBSD, or at least I, decided not to support C90's relatively feeble and broken specification of floating point and wait for C99 to get it right. The wait is long over and the nonstandardness is now a little different. As you may know, this existence of errno is basically a bug. It is especially broken as designed for math functions because requiring the side effect of setting it breaks things like removing sqrt(x) (for x a loop consant) from loops unless the compiler is very clever about this side effect. The compiler may also need to be clever about the side effect of possibly setting IEEE exception flags for sqrt(x), but the exception flags are sticky and low-level (unlike errno), so it doesn't need to be so clever. I believe that C99 relaxed the requirement on setting errno to simplify such optimization. The current nonstandardness is mainly related to setting the exception flags, and many unimplemented functions. The Sun parts of fdlibm attempt to set the exception flags, but were often defeated by invalid compile-time constant folding last time I checked (long ago). The assembler parts are not very careful about the exception flags. > 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. Oops. The man pages even claim to set errno. > >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. It is safe enough for strict C90, but it adds overhead. For unstrict C90 == C90 less errno plus IEEEish extensions, and for C99 with IEEE support, it breaks returning NaNs for domain errors. E.g., it causes acos(2.0) to return the preposterous nonstandard value 0 with errno set to EDOM instead of a relatively standard non-value "NaN" with errno unchanged. See k_standard.c. It should not adjust the value except possibly in the (_LIB_VERSION == _SVID_) case, but k_standard.c is not passed the original value and I was too lazy to fix its interface. Bruce