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 <kenneth@whitecape.org>
Reviewed-by: Timothy Arceri <timothy.arceri@collabora.com>
This commit is contained in:
Kenneth Graunke
2016-11-12 11:27:17 -08:00
parent 5debfeb86f
commit 9c676a6427

View File

@@ -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);
instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var));
}
ir_rvalue *rvalue = 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);
}
*out_rvalue = rvalue;
} else {
if (!error_emitted)