summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2016-11-12 11:27:17 -0800
committerKenneth Graunke <[email protected]>2016-11-12 22:08:15 -0800
commit9c676a64273f32c7fb3f2b6973399af1d7f24d46 (patch)
tree45b0f1920e63551e2d4c1e6512b10943bc6b27f2
parent5debfeb86f524b06aa3b80f9855947a57b5f91e8 (diff)
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 <[email protected]> Reviewed-by: Timothy Arceri <[email protected]>
-rw-r--r--src/compiler/glsl/ast_to_hir.cpp19
1 files changed, 11 insertions, 8 deletions
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)