From Bugzilla Helper: User-Agent: Mozilla/4.76 [en] (X11; U; Linux 2.4.2-2enterprise i686) Description of problem: Function reading a string an making a bit of arithmetic. When compiled without optimization it works (returning 1.0) and with -O it returns -NaN How reproducible: Always Steps to Reproduce: Everytime but under other circumstances it seems. I do not suggest you try those but instead look at the informations provided at http://veillard.com/gcc.bug 1. rebuild libxml and libxslt from CVS adding --without-debug at libxml configure 2. run libxslt testsuite 3. the docbook formatting tests fails Actual Results: function returns a Nan when parsing a "1" Expected Results: function returns a 1.0 when parsing a "1" Additional info: Here is an excerpt of the log on my site, it also include objdump the C code fragment and the same information when compiled without -O I really think it's a compiler bug (well I would be happy if it wasn't the case), how can I avoid it ? Breakpoint 20, xmlXPathCompNumber (ctxt=0x86b6568) at xpath.c:5796 5796 double ret = 0.0; (gdb) info float R7: Empty 0xc016bc61bd0000000000 R6: Empty 0x00000000000000000000 R5: Valid 0x40008000000000000000 +2 R4: Valid 0x40008000000000000000 +2 R3: Valid 0x3fff8000000000000000 +1 R2: Valid 0x40008000000000000000 +2 R1: Valid 0x40008000000000000000 +2 =>R0: Valid 0x40008000000000000000 +2 Status Word: 0x0045 IE ZE SF TOP: 0 Control Word: 0x037f IM DM ZM OM UM PM PC: Extended Precision (64-bits) RC: Round to nearest Tag Word: 0xf000 Instruction Pointer: 0x23:0x0804f939 Operand Pointer: 0x2b:0x080a710c Opcode: 0xdae9 (gdb) n 5797 double mult = 1, tmp2; (gdb) 5798 int ok = 0, tmp; (gdb) 5799 int exponent = 0; (gdb) 5800 int is_exponent_negative = 0; (gdb) 5802 CHECK_ERROR; (gdb) 5803 if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) { (gdb) 5806 while ((CUR >= '0') && (CUR <= '9')) { (gdb) 5807 tmp = (CUR - '0'); (gdb) 5809 ret = ret * 10.0; (gdb) p tmp $6 = 1 (gdb) p ret $7 = 0 (gdb) p tmp2 No symbol "tmp2" in current context. (gdb) info float R7: Valid 0x3fff8000000000000000 +1 R6: Valid 0x4002a000000000000000 +10 =>R5: Valid 0xffffc000000000000000 Real Indefinite (QNaN) R4: Valid 0x40008000000000000000 +2 R3: Valid 0x3fff8000000000000000 +1 R2: Valid 0x40008000000000000000 +2 R1: Valid 0x40008000000000000000 +2 R0: Special 0x40008000000000000000 +2 Status Word: 0x2845 IE ZE SF TOP: 5 Control Word: 0x037f IM DM ZM OM UM PM PC: Extended Precision (64-bits) RC: Round to nearest Tag Word: 0x0002 Instruction Pointer: 0x23:0x08090ef5 Operand Pointer: 0x2b:0xbfffef20 Opcode: 0xd8c9 (gdb) n 5812 NEXT; (gdb) p ret $9 = -nan(0x8000000000000) (gdb) n 5813 } (gdb) n 5814 if (CUR == '.') { (gdb) 5825 if ((CUR == 'e') || (CUR == 'E')) { (gdb) 5839 PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0, (gdb) s xmlXPathNewFloat (val=-nan(0x8000000000000)) at xpath.c:2031 2031 ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject)); (gdb) Daniel
A self-contained (and if possible small) testcase would be highly appreciated (like the function with all relevant typedefs plus another function which would give it the right arguments).
Sorry, would not work. The problem was exhibited "in context", i.e. only within the largest runs of the libxslt regression tests. Simples testcase do not trigger the bug. I really doubt that a stripped version of just the scanning of a string would reproduce the bug at all. That is the reason why I went through the work of extracting the generated assembly code. The fact that the processor floating point file is clean before entering the function and get a NaN inserted by doing a + and a * is unexplainable to me. But it does happen in some rare cases. It was very hard to track of course, but repetable in a very specific case. CHECK_ERROR and XP_ERROR are error detection macros and exit in case they get triggered, they should have no side effect otherwise. #define CHECK_ERROR \ if (ctxt->error != XPATH_EXPRESSION_OK) return #define XP_ERROR(X) \ { xmlXPatherror(ctxt, __FILE__, __LINE__, X); \ ctxt->error = (X); return; } #define CUR (*ctxt->cur) #define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) none of this touches a floating point, Daniel
That's old code and compiler, not much priority anymore ... Daniel
Let's close it, this will never be solved ... Daniel