summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorDanylo Piliaiev <danylo.piliaiev@globallogic.com>2020-08-18 10:41:31 +0300
committerEric Engestrom <eric@engestrom.ch>2020-09-02 21:50:42 +0200
commite8d449071f2cd29af33a223b0f3bc483d9c0ecf6 (patch)
treec4b2013247c12a12cbc47d8bb9724f024645059d /src/compiler
parentb88f0c9d006e6c85aa1d4300c7abab0a09ce4cf3 (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)
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/glsl/lower_vector_insert.cpp33
1 files changed, 32 insertions, 1 deletions
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)
{