Fix front-end bug: Constant folding of array-of-struct index op.

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.
This commit is contained in:
John Kessenich 2016-02-01 11:57:33 -07:00
parent 9d565d9ef8
commit 9df51caba9
3 changed files with 58 additions and 5 deletions

View File

@ -270,6 +270,14 @@ ERROR: node is still EOpNull!
0:128 76.000000 0:128 76.000000
0:128 59.000000 0:128 59.000000
0:128 88.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:? Linker Objects
0:? 'a' (const int) 0:? 'a' (const int)
0:? 1 (const int) 0:? 1 (const int)
@ -356,6 +364,16 @@ ERROR: node is still EOpNull!
0:? 13.000000 0:? 13.000000
0:? 14.000000 0:? 14.000000
0:? 15.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: Linked fragment stage:
@ -622,6 +640,14 @@ ERROR: node is still EOpNull!
0:128 76.000000 0:128 76.000000
0:128 59.000000 0:128 59.000000
0:128 88.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:? Linker Objects
0:? 'a' (const int) 0:? 'a' (const int)
0:? 1 (const int) 0:? 1 (const int)
@ -708,4 +734,14 @@ ERROR: node is still EOpNull!
0:? 13.000000 0:? 13.000000
0:? 14.000000 0:? 14.000000
0:? 15.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)

View File

@ -127,3 +127,15 @@ void foo3()
{ {
mat3x2 r32 = mm2 * mm32; mat3x2 r32 = mm2 * mm32;
} }
struct cag {
int i;
float f;
bool b;
};
const cag a0[3] = cag[3](cag(3, 2.0, true), cag(1, 5.0, true), cag(1, 9.0, false));
void foo4()
{
int a = int(a0[2].f);
}

View File

@ -852,7 +852,7 @@ TIntermTyped* TIntermediate::foldConstructor(TIntermAggregate* aggrNode)
// //
// Constant folding of a bracket (array-style) dereference or struct-like dot // 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(). // all swizzles may go to foldSwizzle().
// //
TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, const TSourceLoc& loc) TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, const TSourceLoc& loc)
@ -862,13 +862,18 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons
TIntermTyped* result = 0; TIntermTyped* result = 0;
int size = dereferencedType.computeNumComponents(); int size = dereferencedType.computeNumComponents();
// arrays, vectors, matrices, all use simple multiplicative math
// while structures need to add up heterogeneous members
int start; int start;
if (node->isStruct()) { if (node->isArray() || ! node->isStruct())
start = size * index;
else {
// it is a structure
assert(node->isStruct());
start = 0; start = 0;
for (int i = 0; i < index; ++i) for (int i = 0; i < index; ++i)
start += (*node->getType().getStruct())[i].type->computeNumComponents(); start += (*node->getType().getStruct())[i].type->computeNumComponents();
} else }
start = size * index;
result = addConstantUnion(TConstUnionArray(node->getAsConstantUnion()->getConstArray(), start, size), node->getType(), loc); result = addConstantUnion(TConstUnionArray(node->getAsConstantUnion()->getConstArray(), start, size), node->getType(), loc);