Bug 32831

Summary: [glsl] division by zero crashes GLSL compiler
Product: Mesa Reporter: Vinson Lee <vlee>
Component: glsl-compilerAssignee: Ian Romanick <idr>
Status: CLOSED FIXED QA Contact:
Severity: critical    
Priority: medium    
Version: 7.10   
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: Generate an error for division by zero in a preprocessor directive

Description Vinson Lee 2011-01-04 13:29:39 UTC
mesa: 6530944b502a0f35b305ee35c1c6f1e32a887721 (master)

A division by zero in a #if statement generates a floating point exception and crashes the preprocessor.


093-divide-by-zero.c
     1	#if (1 / 0)
     2	#endif


$ ../glcpp 093-divide-by-zero.c

(gdb) bt
#0  0x08052c1b in __divdi3 ()
#1  0x0804ebd8 in yyparse (parser=0x8e160e0) at glcpp/glcpp-parse.y:401
#2  0x08050c82 in glcpp_parser_parse (parser=0x8e160e0) at glcpp/glcpp-parse.y:1118
#3  0x0805239f in preprocess (talloc_ctx=0x8e14038, shader=0xbf8eab30, info_log=0xbf8eab34, extensions=0x0, api=0) at glcpp/pp.c:154
#4  0x08052704 in main (argc=2, argv=0xbf8eac04) at glcpp/glcpp.c:123
(gdb) frame 1
#1  0x0804ebd8 in yyparse (parser=0x8e160e0) at glcpp/glcpp-parse.y:401
401			$$ = $1 / $3;
Comment 1 Ian Romanick 2011-01-10 13:20:43 UTC
Created attachment 41859 [details] [review]
Generate an error for division by zero in a preprocessor directive

This matches GCCs behavior, so it should be correct for GLSL as well.  Is this test from an application that is expecting some other behavior?  If so, what is it expecting?  Does this work on other GLSL implementations?
Comment 2 Vinson Lee 2011-01-10 15:37:18 UTC
(In reply to comment #1)
> This matches GCCs behavior, so it should be correct for GLSL as well.  Is this
> test from an application that is expecting some other behavior?  If so, what is
> it expecting?  Does this work on other GLSL implementations?

This test was not from any known application.

NVIDIA, ATI, Intel, and S3 GLSL compilers also crash with a floating point exception. The Apple GLSL compiler does not crash and interprets the division by zero as true.
Comment 3 Ian Romanick 2011-01-10 18:01:44 UTC
(In reply to comment #2)
> (In reply to comment #1)
> > This matches GCCs behavior, so it should be correct for GLSL as well.  Is this
> > test from an application that is expecting some other behavior?  If so, what is
> > it expecting?  Does this work on other GLSL implementations?
> 
> This test was not from any known application.
> 
> NVIDIA, ATI, Intel, and S3 GLSL compilers also crash with a floating point
> exception. The Apple GLSL compiler does not crash and interprets the division
> by zero as true.

Out of curiosity, what does Apple do for 0/0?  It would be interesting to know the actual value generated for arbitrary x/0.  My guess is that it's either x or maximum representable integer with same sign as x.

The crash is fixed in master by the following patch series.  I'm leaving the bug open, but I'm reassigning it to version 7.10.  I want to wait on the cherry pick until we get some resolution as to what the correct behavior is.

commit a302d740bd1e90d3db2b8cee79b2d5ee1220f8bf
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Mon Jan 10 17:38:56 2011 -0800

    glcpp: Refresh autogenerated lexer and parser files.
    
    For the previous commit.

commit 9ca5300b6e781150cec903c73cf5fd8e1deee2f1
Author: Ian Romanick <ian.d.romanick@intel.com>
Date:   Mon Jan 10 13:33:07 2011 -0800

    glcpp: Generate an error for division by zero
    
    When GCC encounters a division by zero in a preprocessor directive, it
    generates an error.  Since the GLSL spec says that the GLSL
    preprocessor behaves like the C preprocessor, we should generate that
    same error.
    
    It's worth noting that I cannot find any text in the C99 spec that
    says this should be an error.  The only text that I can find is line 5
    on page 82 (section 6.5.5 Multiplicative Opertors), which says,
    
        "The result of the / operator is the quotient from the division of
        the first operand by the second; the result of the % operator is
        the remainder. In both operations, if the value of the second
        operand is zero, the behavior is undefined."
    
    Fixes 093-divide-by-zero.c test and bugzilla #32831.
    
    NOTE: This is a candidate for the 7.9 and 7.10 branches.
Comment 4 Vinson Lee 2011-01-10 23:26:58 UTC
(In reply to comment #3)
> Out of curiosity, what does Apple do for 0/0?  It would be interesting to know
> the actual value generated for arbitrary x/0.  My guess is that it's either x
> or maximum representable integer with same sign as x.


The Apple GLSL compiler's preprocessor interprets 0/0 as true.
(0 / 0) - true
(1 / 0) - true
(0 / 1) - false
(1 / 1) - true
((0 / 0) > 0) - true
((1 / 0) > 0) - true
((0 / 0) < 0) - false
((1 / 0) < 0) - false
((-1 / 0) > 0) - true
((-1 / 0) < 0) - false
Comment 5 Ian Romanick 2011-01-25 17:36:51 UTC
Fixed by ef2f4b546946a4f97af602e5f52227d552a58247 (7.9) and 50d40edb8ce24e9725a00b8eb3ce3b2d4bb16d63 (7.10).
Comment 6 Vinson Lee 2011-04-13 20:06:00 UTC
mesa: a9a02c8a39620515ec9fd0d774ce329cf67ecb4e (master)

Verified fixed.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.