From: Kenneth Graunke Date: Sat, 12 Nov 2016 19:27:17 +0000 (-0800) Subject: glsl: Fix assert fails when assignment expressions are in array sizes. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9c676a64273;p=mesa.git glsl: Fix assert fails when assignment expressions are in array sizes. Karol Herbst's fuzzing efforts discovered that we would hit the following assert: assert(dummy_instructions.is_empty()); when processing an illegal array size expression of float[(1=1)?1:1] t; In do_assignment, we realized we needed an rvalue for (1 = 1), and generated a temporary variable and assignment from the RHS. We've already flagged an error (non-lvalue in assignment), and return a bogus value as the rvalue. But process_array_size sees the bogus value, which happened to be a constant expression, and rightly assumes that processing a constant expression shouldn't have generated any code. instructions. To handle this, make do_assignment not generate any temps or assignments when it's already raised an error - just return an error value directly. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98694 Signed-off-by: Kenneth Graunke Reviewed-by: Timothy Arceri --- diff --git a/src/compiler/glsl/ast_to_hir.cpp b/src/compiler/glsl/ast_to_hir.cpp index 24067b6ac0c..9b8678c04aa 100644 --- a/src/compiler/glsl/ast_to_hir.cpp +++ b/src/compiler/glsl/ast_to_hir.cpp @@ -1001,17 +1001,20 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state, * i = j += 1; */ if (needs_rvalue) { - ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp", - ir_var_temporary); - instructions->push_tail(var); - instructions->push_tail(assign(var, rhs)); - + ir_rvalue *rvalue; if (!error_emitted) { - ir_dereference_variable *deref_var = new(ctx) ir_dereference_variable(var); + ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp", + ir_var_temporary); + instructions->push_tail(var); + instructions->push_tail(assign(var, rhs)); + + ir_dereference_variable *deref_var = + new(ctx) ir_dereference_variable(var); instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var)); + rvalue = new(ctx) ir_dereference_variable(var); + } else { + rvalue = ir_rvalue::error_value(ctx); } - ir_rvalue *rvalue = new(ctx) ir_dereference_variable(var); - *out_rvalue = rvalue; } else { if (!error_emitted)