diff options
author | Danylo Piliaiev <danylo.piliaiev@globallogic.com> | 2020-08-18 10:41:31 +0300 |
---|---|---|
committer | Dylan Baker <dylan.c.baker@intel.com> | 2020-08-21 12:55:46 -0700 |
commit | 831473e56e378f985615ecc2683e7cdaf74047c3 (patch) | |
tree | d6f79a09f3baec7839207a382114dc2be0d337c8 | |
parent | b3510789c294c2eeca336002e63b4771a9a61bf3 (diff) |
glsl: Eliminate out-of-bounds triop_vector_insert
Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says:
"In the subsections described above for array, vector, matrix and
structure accesses, any out-of-bounds access produced undefined
behavior.... Out-of-bounds writes may be discarded or overwrite
other variables of the active program."
Fixes crashes when dereferencing gl_ClipDistance and gl_TessLevel*, e.g:
int index = -1;
gl_ClipDistance[index] = -1;
When LowerCombinedClipCullDistance is true.
CC: <mesa-stable@lists.freedesktop.org>
Signed-off-by: Danylo Piliaiev <danylo.piliaiev@globallogic.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Marcin Ĺšlusarz <marcin.slusarz@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6363>
(cherry picked from commit e802bff69ee74983215d0c2b7e213fca6d68a97d)
-rw-r--r-- | .pick_status.json | 2 | ||||
-rw-r--r-- | src/compiler/glsl/lower_vector_insert.cpp | 33 |
2 files changed, 33 insertions, 2 deletions
diff --git a/.pick_status.json b/.pick_status.json index 68e022102d3..b7a38581c4a 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -103,7 +103,7 @@ "description": "glsl: Eliminate out-of-bounds triop_vector_insert", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "master_sha": null, "because_sha": null }, diff --git a/src/compiler/glsl/lower_vector_insert.cpp b/src/compiler/glsl/lower_vector_insert.cpp index ceaa5887c8a..81ef0491c3a 100644 --- a/src/compiler/glsl/lower_vector_insert.cpp +++ b/src/compiler/glsl/lower_vector_insert.cpp @@ -32,7 +32,8 @@ namespace { class vector_insert_visitor : public ir_rvalue_visitor { public: vector_insert_visitor(bool lower_nonconstant_index) - : progress(false), lower_nonconstant_index(lower_nonconstant_index) + : progress(false), lower_nonconstant_index(lower_nonconstant_index), + remove_assignment(false) { factory.instructions = &factory_instructions; } @@ -43,11 +44,13 @@ public: } virtual void handle_rvalue(ir_rvalue **rv); + virtual ir_visitor_status visit_leave(ir_assignment *expr); ir_factory factory; exec_list factory_instructions; bool progress; bool lower_nonconstant_index; + bool remove_assignment; }; } /* anonymous namespace */ @@ -68,6 +71,21 @@ vector_insert_visitor::handle_rvalue(ir_rvalue **rv) ir_constant *const idx = expr->operands[2]->constant_expression_value(factory.mem_ctx); if (idx != NULL) { + unsigned index = idx->value.u[0]; + + if (index >= expr->operands[0]->type->vector_elements) { + /* Section 5.11 (Out-of-Bounds Accesses) of the GLSL 4.60 spec says: + * + * In the subsections described above for array, vector, matrix and + * structure accesses, any out-of-bounds access produced undefined + * behavior.... Out-of-bounds writes may be discarded or overwrite + * other variables of the active program. + */ + this->remove_assignment = true; + this->progress = true; + return; + } + /* Replace (vector_insert (vec) (scalar) (index)) with a dereference of * a new temporary. The new temporary gets assigned as * @@ -136,6 +154,19 @@ vector_insert_visitor::handle_rvalue(ir_rvalue **rv) base_ir->insert_before(factory.instructions); } +ir_visitor_status +vector_insert_visitor::visit_leave(ir_assignment *ir) +{ + ir_rvalue_visitor::visit_leave(ir); + + if (this->remove_assignment) { + ir->remove(); + this->remove_assignment = false; + } + + return visit_continue; +} + bool lower_vector_insert(exec_list *instructions, bool lower_nonconstant_index) { |