ir_constant: Don't assert on out-of-bounds array accesses
authorIan Romanick <ian.d.romanick@intel.com>
Tue, 17 Aug 2010 19:57:28 +0000 (12:57 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Tue, 17 Aug 2010 20:00:03 +0000 (13:00 -0700)
Several optimization paths, including constant folding, can lead to
accessing an ir_constant array with an out of bounds index.  The GLSL
spec lets us produce "undefined" results, but it does not let us
crash.

Fixes piglit test case glsl-array-bounds-01 and glsl-array-bounds-03.

src/glsl/ir.cpp

index dd059e470d5d412031c5785d003758e877dd4ddb..ebb592792ba9488d294e6ddf7c7d742d3d8f1ede 100644 (file)
@@ -519,7 +519,21 @@ ir_constant *
 ir_constant::get_array_element(unsigned i) const
 {
    assert(this->type->is_array());
-   assert(i < this->type->length);
+
+   /* From page 35 (page 41 of the PDF) of the GLSL 1.20 spec:
+    *
+    *     "Behavior is undefined if a shader subscripts an array with an index
+    *     less than 0 or greater than or equal to the size the array was
+    *     declared with."
+    *
+    * Most out-of-bounds accesses are removed before things could get this far.
+    * There are cases where non-constant array index values can get constant
+    * folded.
+    */
+   if (int(i) < 0)
+      i = 0;
+   else if (i >= this->type->length)
+      i = this->type->length - 1;
 
    return array_elements[i];
 }