Mesa (10.6): glsl: avoid compiler' s segfault when processing operators with void arguments

Emil Velikov evelikov at kemper.freedesktop.org
Thu Aug 20 12:52:57 UTC 2015


Module: Mesa
Branch: 10.6
Commit: 4a2a49040e6891355a80b582932c5a3cffaa3c16
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4a2a49040e6891355a80b582932c5a3cffaa3c16

Author: Renaud Gaubert <renaud at lse.epita.fr>
Date:   Sat Jul 11 19:38:10 2015 +0200

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 at lse.epita.fr>
Reviewed-by: Gabriel Laskar <gabriel at lse.epita.fr>
Reviewed-by: Samuel Iglesias Gonsalvez <siglesias at igalia.com>
(cherry picked from commit 7b9ebf879b6f35038996805a641667f00d93c4b7)
Nominated-by: Mark Janes <mark.a.janes at intel.com>

---

 src/glsl/ast_function.cpp |    9 ++++++++-
 src/glsl/ast_to_hir.cpp   |    9 ++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp
index 7583613..8d2c801 100644
--- a/src/glsl/ast_function.cpp
+++ b/src/glsl/ast_function.cpp
@@ -1773,7 +1773,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;
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp
index a0154f1..05d00d8 100644
--- a/src/glsl/ast_to_hir.cpp
+++ b/src/glsl/ast_to_hir.cpp
@@ -1270,7 +1270,14 @@ ast_expression::do_hir(exec_list *instructions,
        *    applied to one operand that can make them match, in which
        *    case this conversion is done."
        */
-      if ((!apply_implicit_conversion(op[0]->type, op[1], state)
+
+      if (op[0]->type == glsl_type::void_type || op[1]->type == glsl_type::void_type) {
+         _mesa_glsl_error(& loc, state, "`%s':  wrong operand types: "
+                         "no operation `%1$s' exists that takes a left-hand "
+                         "operand of type 'void' or a right operand of type "
+                         "'void'", (this->oper == ast_equal) ? "==" : "!=");
+         error_emitted = true;
+      } else if ((!apply_implicit_conversion(op[0]->type, op[1], state)
            && !apply_implicit_conversion(op[1]->type, op[0], state))
           || (op[0]->type != op[1]->type)) {
          _mesa_glsl_error(& loc, state, "operands of `%s' must have the same "




More information about the mesa-commit mailing list