From owner-freebsd-bugs@FreeBSD.ORG Thu Jan 4 01:36:15 2007 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 35B7E16A416; Thu, 4 Jan 2007 01:36:15 +0000 (UTC) (envelope-from das@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [69.147.83.40]) by mx1.freebsd.org (Postfix) with ESMTP id 0D39513C442; Thu, 4 Jan 2007 01:36:15 +0000 (UTC) (envelope-from das@FreeBSD.org) Received: from freefall.freebsd.org (das@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id l041aEfS047643; Thu, 4 Jan 2007 01:36:14 GMT (envelope-from das@freefall.freebsd.org) Received: (from das@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id l041aERj047639; Thu, 4 Jan 2007 01:36:14 GMT (envelope-from das) Date: Thu, 4 Jan 2007 01:36:14 GMT From: David Schultz Message-Id: <200701040136.l041aERj047639@freefall.freebsd.org> To: tvrusso@sandia.gov, das@FreeBSD.org, freebsd-bugs@FreeBSD.org, kan@FreeBSD.org Cc: Subject: Re: kern/94583: [libm] std::isnan()/std::isinf() are not identical to isnan() and isinf() X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Jan 2007 01:36:15 -0000 Synopsis: [libm] std::isnan()/std::isinf() are not identical to isnan() and isinf() State-Changed-From-To: open->analyzed State-Changed-By: das State-Changed-When: Thu Jan 4 01:16:40 UTC 2007 State-Changed-Why: This appears to be a regression in glibstdc++ 3.4, or our configuration of it. Here's the problem. In our math.h, isnan() is defined as a macro as follows: #define isnan(x) \ ((sizeof (x) == sizeof (float)) ? isnanf(x) \ : (sizeof (x) == sizeof (double)) ? isnan(x) \ : __isnanl(x)) This is as suggested in the C99 standard. Then src/contrib/libstdc++/include/c_std/std_cmath.h plays a little game to move isnan() out of the global namespace: namespace __gnu_cxx { [...] template inline int __capture_isnan(_Tp __f) { return isnan(__f); } [...] } [...] #undef isnan [...] namespace __gnu_cxx [...] template inline int isnan(_Tp __f) { return __capture_isnan(__f); } [...] } The trouble with this is that once the macro is expanded, the call to isnan() within __capture_isnan() simply refers to the symbol isnan() within the __gnu_cxx namespace, which is a function that refers back to __capture_isnan(), and the result is an infinite loop. The following workaround (along with corresponding changes for isinf()) fixes the problem, but I don't understand the internals of libstdc++ well enough to know if it's the best solution. template inline int __capture_isnan(_Tp __f) { using ::isnan; return isnan(__f); } ^^^^^^^^^^^^^^ I'm forwarding this to kan@ to take a look at. This might need to be taken to the GNU people, rather than fixed locally, or there may be a better fix. I brought up some similar issues regarding isnan() in C++ with them in early 2003. As I recall, Loren and someone with Red Hat were very helpful, but Gaby's combative attitude resulted in lots of wasted time, and ultimately nothing got fixed. I'd rather not deal with that again if I can avoid it. 8) Responsible-Changed-From-To: freebsd-bugs->kan Responsible-Changed-By: das Responsible-Changed-When: Thu Jan 4 01:16:40 UTC 2007 Responsible-Changed-Why: http://www.freebsd.org/cgi/query-pr.cgi?pr=94583