glsl: Don't assert when the value returned by a function has no rvalue
authorIan Romanick <ian.d.romanick@intel.com>
Sun, 23 Jan 2011 01:47:05 +0000 (17:47 -0800)
committerIan Romanick <ian.d.romanick@intel.com>
Sun, 23 Jan 2011 02:04:40 +0000 (18:04 -0800)
The rvalue of the returned value can be NULL if the shader says
'return foo();' and foo() is a function that returns void.

Existing GLSL specs do *NOT* say that this is an error.  The type of
the return value is void.  If the return type of the function is also
void, then this should compile without error.  I expect that future
versions of the GLSL spec will fix this (wink, wink, nudge, nudge).

Fixes piglit test glsl-1.10/compiler/expressions/return-01.vert and
bugzilla #33308.

NOTE: This is a candidate for the 7.9 and 7.10 branches.

src/glsl/ast_to_hir.cpp

index 1bca3ec..34d61b8 100644 (file)
@@ -3010,27 +3010,26 @@ ast_jump_statement::hir(exec_list *instructions,
       assert(state->current_function);
 
       if (opt_return_value) {
-        if (state->current_function->return_type->base_type ==
-            GLSL_TYPE_VOID) {
-           YYLTYPE loc = this->get_location();
-
-           _mesa_glsl_error(& loc, state,
-                            "`return` with a value, in function `%s' "
-                            "returning void",
-                            state->current_function->function_name());
-        }
-
         ir_rvalue *const ret = opt_return_value->hir(instructions, state);
-        assert(ret != NULL);
+
+        /* The value of the return type can be NULL if the shader says
+         * 'return foo();' and foo() is a function that returns void.
+         *
+         * NOTE: The GLSL spec doesn't say that this is an error.  The type
+         * of the return value is void.  If the return type of the function is
+         * also void, then this should compile without error.  Seriously.
+         */
+        const glsl_type *const ret_type =
+           (ret == NULL) ? glsl_type::void_type : ret->type;
 
         /* Implicit conversions are not allowed for return values. */
-        if (state->current_function->return_type != ret->type) {
+        if (state->current_function->return_type != ret_type) {
            YYLTYPE loc = this->get_location();
 
            _mesa_glsl_error(& loc, state,
                             "`return' with wrong type %s, in function `%s' "
                             "returning %s",
-                            ret->type->name,
+                            ret_type->name,
                             state->current_function->function_name(),
                             state->current_function->return_type->name);
         }