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:
@@ -1001,17 +1001,20 @@ do_assignment(exec_list *instructions, struct _mesa_glsl_parse_state *state,
|
|||||||
* i = j += 1;
|
* i = j += 1;
|
||||||
*/
|
*/
|
||||||
if (needs_rvalue) {
|
if (needs_rvalue) {
|
||||||
ir_variable *var = new(ctx) ir_variable(rhs->type, "assignment_tmp",
|
ir_rvalue *rvalue;
|
||||||
ir_var_temporary);
|
|
||||||
instructions->push_tail(var);
|
|
||||||
instructions->push_tail(assign(var, rhs));
|
|
||||||
|
|
||||||
if (!error_emitted) {
|
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",
|
||||||
instructions->push_tail(new(ctx) ir_assignment(lhs, deref_var));
|
ir_var_temporary);
|
||||||
}
|
instructions->push_tail(var);
|
||||||
ir_rvalue *rvalue = new(ctx) ir_dereference_variable(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;
|
*out_rvalue = rvalue;
|
||||||
} else {
|
} else {
|
||||||
if (!error_emitted)
|
if (!error_emitted)
|
||||||
|
Reference in New Issue
Block a user