Fix front-end bug: Constant folding of array-of-struct index op.
authorJohn Kessenich <cepheus@frii.com>
Mon, 1 Feb 2016 18:57:33 +0000 (11:57 -0700)
committerJohn Kessenich <cepheus@frii.com>
Mon, 1 Feb 2016 18:57:33 +0000 (11:57 -0700)
If a constant object was both an array and a structure, and was
indexed with a constant, the arrayness was ignored and the wrong
subconstant selected.  This fixes that.

Test/baseResults/constFold.frag.out
Test/constFold.frag
glslang/MachineIndependent/Constant.cpp

index c03d865..f5c3e9c 100644 (file)
@@ -270,6 +270,14 @@ ERROR: node is still EOpNull!
 0:128            76.000000
 0:128            59.000000
 0:128            88.000000
+0:138  Function Definition: foo4( (global void)
+0:138    Function Parameters: 
+0:140    Sequence
+0:140      Sequence
+0:140        move second child to first child (temp int)
+0:140          'a' (temp int)
+0:140          Constant:
+0:140            9 (const int)
 0:?   Linker Objects
 0:?     'a' (const int)
 0:?       1 (const int)
@@ -356,6 +364,16 @@ ERROR: node is still EOpNull!
 0:?       13.000000
 0:?       14.000000
 0:?       15.000000
+0:?     'a0' (const 3-element array of structure{global int i, global float f, global bool b})
+0:?       3 (const int)
+0:?       2.000000
+0:?       true (const bool)
+0:?       1 (const int)
+0:?       5.000000
+0:?       true (const bool)
+0:?       1 (const int)
+0:?       9.000000
+0:?       false (const bool)
 
 
 Linked fragment stage:
@@ -622,6 +640,14 @@ ERROR: node is still EOpNull!
 0:128            76.000000
 0:128            59.000000
 0:128            88.000000
+0:138  Function Definition: foo4( (global void)
+0:138    Function Parameters: 
+0:140    Sequence
+0:140      Sequence
+0:140        move second child to first child (temp int)
+0:140          'a' (temp int)
+0:140          Constant:
+0:140            9 (const int)
 0:?   Linker Objects
 0:?     'a' (const int)
 0:?       1 (const int)
@@ -708,4 +734,14 @@ ERROR: node is still EOpNull!
 0:?       13.000000
 0:?       14.000000
 0:?       15.000000
+0:?     'a0' (const 3-element array of structure{global int i, global float f, global bool b})
+0:?       3 (const int)
+0:?       2.000000
+0:?       true (const bool)
+0:?       1 (const int)
+0:?       5.000000
+0:?       true (const bool)
+0:?       1 (const int)
+0:?       9.000000
+0:?       false (const bool)
 
index 81c718c..97c3b2b 100644 (file)
@@ -127,3 +127,15 @@ void foo3()
 {\r
     mat3x2 r32 = mm2 * mm32;\r
 }\r
+\r
+struct cag {\r
+    int   i;\r
+    float f;\r
+    bool  b;\r
+};\r
+const cag a0[3] = cag[3](cag(3, 2.0, true), cag(1, 5.0, true), cag(1, 9.0, false));\r
+\r
+void foo4()\r
+{\r
+    int a = int(a0[2].f);\r
+}
\ No newline at end of file
index a0bb8de..b4d0695 100644 (file)
@@ -852,7 +852,7 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode)
 
 //
 // Constant folding of a bracket (array-style) dereference or struct-like dot
-// dereference.  Can handle any thing except a multi-character swizzle, though
+// dereference.  Can handle anything except a multi-character swizzle, though
 // all swizzles may go to foldSwizzle().
 //
 TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, const TSourceLoc& loc)
@@ -861,14 +861,19 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons
     dereferencedType.getQualifier().storage = EvqConst;
     TIntermTyped* result = 0;
     int size = dereferencedType.computeNumComponents();
-    
+
+    // arrays, vectors, matrices, all use simple multiplicative math
+    // while structures need to add up heterogeneous members
     int start;
-    if (node->isStruct()) {
+    if (node->isArray() || ! node->isStruct())
+        start = size * index;
+    else {
+        // it is a structure
+        assert(node->isStruct());
         start = 0;
         for (int i = 0; i < index; ++i)
             start += (*node->getType().getStruct())[i].type->computeNumComponents();
-    } else
-        start = size * index;
+    }
 
     result = addConstantUnion(TConstUnionArray(node->getAsConstantUnion()->getConstArray(), start, size), node->getType(), loc);