Bug 7298 - FP divide by zero exception when printing double 0.0
Summary: FP divide by zero exception when printing double 0.0
Status: RESOLVED DUPLICATE of bug 6152
Alias: None
Product: uClibc
Classification: Unclassified
Component: Other (show other bugs)
Version: unspecified
Hardware: Other Linux
: P5 major
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-08-07 17:23 UTC by Zia
Modified: 2014-12-15 13:08 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Zia 2014-08-07 17:23:12 UTC
The file _fpmaxtpstr.c contains code that looks like this:
============================================================
… 
#define zeroisnegative(x)    ((1./(x)) < 0) 
… 

ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, 
                                                                          __fp_outfunc_t fp_outfunc) 
…. 
               if (x == 0) {                                                      /* Handle 0 now to avoid false positive. */ 
#ifdef __UCLIBC_HAVE_SIGNED_ZERO__ 
                              if (zeroisnegative(x)) { /* Handle 'signed' zero. */ 
                                            *sign_str = '-'; 
                              } 
#endif /* __UCLIBC_HAVE_SIGNED_ZERO__ */ 
                              exp = -1; 
                              goto GENERATE_DIGITS; 
               } 
============================================================

The "zeroisnegative" check causes FP divide by zero exceptions with any simple program that prints a double value, like:

printf("%f",(double)0.0);

When the divide by zero mask is disabled.

A better way to do the check would be to check the bits of the value to see if they're all "0x0", or not, by casting to an appropriate integer type.

Here's a simple reproducer:

#include <stdio.h>

main()
{
    short s;
    // Unmask div-by-zero, invalid, overflow
    __asm__("fstcw %0\n\t"
            "andw $0xf2, %0\n\t"
            "fldcw %0" : "+m" (s));
    printf("\n%f\n",(double)1.0); // this works
    printf("\n%f\n",(double)0.0); // this doesn't
}
Comment 1 Bernhard Reutner-Fischer 2014-12-15 13:08:03 UTC

*** This bug has been marked as a duplicate of bug 6152 ***