This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: More instantiation problems under hpux


In article <200201162011.g0GKB97f029662@hiauly1.hia.nrc.ca>,
"John David Anglin" <dave@hiauly1.hia.nrc.ca> writes:

>> Can you confirm that this situation exists on hpux as well (and is not
>> failing the same assertion for an alternate reason)?  Here is one was
>> to do it:

> The test fails on type float and the value of t is Inf (0x7f80000).
> The system header defines FLT_MAX as (float)3.40282347e+38.  Putting
> this in a little C program I find that this converts to the hex value
> 0x7f7fffff.  This is correct.

Dave, thank you for gaining this information.  At first glance, your
system appears to be failing the test for a different reason than
covered by my theory.  However, I would like to revise my theory
slightly to fit all the facts now in (OK, not so minor; replace all
"FP register to memory" references with "double to float").  I can
also now explain how sparc-sun-solaris2.7 also fails without building
gdb there.

>  So, why isn't the fail bit set?

Very good question.  It is a question that I can investigate myself
since I can see it on my platform (as of today when built as
below). ;-/

When I run istream_extractor_arith.st-exe as generated with 'make
check-script', I see this under the debugger at the assertion failure
point:

(gdb) up
#3  0x08068273 in bool test12_aux<float>(bool) (integer_type=false)
    at /usr/users/rittle/outside-cvs-src/gcc-mainline/libstdc++-v3/testsuite/27_io/istream_extractor_arith.cc:539
539       VERIFY(is.fail());
Current language:  auto; currently c++
(gdb) print t
$1 = Inf

This is the exact same behavior you just reported.  I think I must
have been somewhat sloppier at debugging this myself in my own
environment back in Dec. than the technique I provided for you to use.

To further debug this, I did the following.  Under gdb, set break
point on strtod.  Continue until call relates to the failing test case
pops up.

(gdb) finish
Run till exit from #0  strtod (
    s00=0x80a9a8c "1234567890123456789012345678901234567890", se=0xbfbfe268)
    at /usr/src/lib/libc/../libc/stdlib/strtod.c:1196
0x0807402f in std::num_get<char, std::istreambuf_iterator<char, std::char_traits<char> > >::do_get(std::istreambuf_iterator<char, std::char_traits<char> >, std::istreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, std::_Ios_Iostate&, float&) const (this=0x80a3080, __io=@0xbfbfe38c, __err=@0xbfbfe338, 
    __v=@0x3e)
    at /usr/users/rittle/tmp/gcc-build-latour-mainline-0115/i386-unknown-freebsd4.4/libstdc++-v3/include/bits/basic_string.h:752
752           {
Value returned is $1 = 1.2345678901234568e+39
Current language:  auto; currently c++
(gdb) print errno
$2 = 0

Looks OK to me.  However, look at the code at the call site in
question (note how the evil macro check allows the behavior we see on
various platforms yet probably allows this to work fine in those
environments supporting strtof):

631     #ifdef _GLIBCPP_USE_C99
632           float __f = strtof(__xtrc.c_str(), &__sanity);
633     #else
634           float __f = static_cast<float>(strtod(__xtrc.c_str(), &__sanity));
635     #endif
636           if (!(__err & ios_base::failbit)
637               && __sanity != __xtrc.c_str() && *__sanity == '\0' && errno == 0)

I am afraid that it is not correct to check errno == 0 in order to
declare a non-Inf value in __f since the return value from strtod must
fit in a double not a float.  The cast to a float might
truncate/convert to Inf.  That conversion doesn't set errno on
overflow (according to my understanding and seen behavior).

Since it is checked for by configure, I don't think the fix is to
simply use isinf() to check __f.  Also, I'm guessing that people that
have strtof would prefer this fix inside the #else section, right?
BTW, for you "all the world is a VAX" fans or anti-fans, from isinf(3)
on my platform: "Neither the VAX nor the Tahoe floating point have
distinguished values for either infinity or not-a-number.  These
routines always return 0 on those architectures."  Thus, the check
against overflow might need to be more complex for some architectures
to get this absolutely portable...

Sorry I misattributed the behavior I saw on my platform to another
known issue without looking closer.  Good thing I didn't paper over
the problem by changing the test case as I proposed to do.  Luckily,
this appears to be the only place we do this type of thing other than
in libstdc++-v3/include/c_std/cmath (systems without e.g. sinhf will
not handle the conversion of the return type of sinh properly for the
same reason the above code has an issue).

Regards,
Loren


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]