glsl: avoid compiler's segfault when processing operators with void arguments

This is done by returning an rvalue of type void in the
ast_function_expression::hir function instead of a void expression.

This produces (in the case of the ternary) an hir with a call
to the void returning function and an assignment of a void variable
which will be optimized out (the assignment) during the optimization
pass.

This fix results in having a valid subexpression in the many
different cases where the subexpressions are functions whose
return values are void.

Thus preventing to dereference NULL in the following cases:
  * binary operator
  * unary operators
  * ternary operator
  * comparison operators (except equal and nequal operator)

Equal and nequal had to be handled as a special case because
instead of segfaulting on a forbidden syntax it was now accepting
expressions with a void return value on either (or both) side of
the expression.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85252

Signed-off-by: Renaud Gaubert <renaud@lse.epita.fr>
Reviewed-by: Gabriel Laskar <gabriel@lse.epita.fr>
Reviewed-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
This commit is contained in:
Renaud Gaubert
2015-07-11 19:38:10 +02:00
committed by Samuel Iglesias Gonsalvez
parent 779cabfc7d
commit 7b9ebf879b
2 changed files with 16 additions and 2 deletions
+8 -1
View File
@@ -1785,7 +1785,14 @@ ast_function_expression::hir(exec_list *instructions,
/* an error has already been emitted */
value = ir_rvalue::error_value(ctx);
} else {
value = generate_call(instructions, sig, &actual_parameters, state);
value = generate_call(instructions, sig, &actual_parameters, state);
if (!value) {
ir_variable *const tmp = new(ctx) ir_variable(glsl_type::void_type,
"void_var",
ir_var_temporary);
instructions->push_tail(tmp);
value = new(ctx) ir_dereference_variable(tmp);
}
}
return value;