translator: Fix validation sometimes modifying builtins.
When validating some shaders with out-of-bounds array indexes,
we would write the sanitized index into the global symbol table.
We would then overwrite a wrong value for the builtin. This
fixes the WebGL test extensions/webgl-draw-buffers-max-draw-buffers.
Also mark const on as many uses ConstantUnion as we can.
BUG=angleproject:993
Change-Id: I110efaf1b7b0158b08b704277e3bc2472437902c
Reviewed-on: https://chromium-review.googlesource.com/268962
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index eb9328c..cd7ffc4 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1814,7 +1814,7 @@
TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
- TConstantUnion *unionArray;
+ const TConstantUnion *unionArray;
if (tempConstantNode) {
unionArray = tempConstantNode->getUnionArrayPointer();
@@ -1868,7 +1868,7 @@
}
if (tempConstantNode) {
- TConstantUnion* unionArray = tempConstantNode->getUnionArrayPointer();
+ TConstantUnion *unionArray = tempConstantNode->getUnionArrayPointer();
int size = tempConstantNode->getType().getCols();
typedNode = intermediate.addConstantUnion(&unionArray[size*index], tempConstantNode->getType(), line);
} else {
@@ -2202,6 +2202,8 @@
}
else
{
+ int safeIndex = -1;
+
if (baseExpression->isArray())
{
if (index >= baseExpression->getType().getArraySize())
@@ -2211,13 +2213,13 @@
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
- index = baseExpression->getType().getArraySize() - 1;
+ safeIndex = baseExpression->getType().getArraySize() - 1;
}
else if (baseExpression->getQualifier() == EvqFragData && index > 0 && !isExtensionEnabled("GL_EXT_draw_buffers"))
{
error(location, "", "[", "array indexes for gl_FragData must be zero when GL_EXT_draw_buffers is disabled");
recover();
- index = 0;
+ safeIndex = 0;
}
}
else if ((baseExpression->isVector() || baseExpression->isMatrix()) && baseExpression->getType().getNominalSize() <= index)
@@ -2227,10 +2229,18 @@
std::string extraInfo = extraInfoStream.str();
error(location, "", "[", extraInfo.c_str());
recover();
- index = baseExpression->getType().getNominalSize() - 1;
+ safeIndex = baseExpression->getType().getNominalSize() - 1;
}
- indexConstantUnion->getUnionArrayPointer()->setIConst(index);
+ // Don't modify the data of the previous constant union, because it can point
+ // to builtins, like gl_MaxDrawBuffers. Instead use a new sanitized object.
+ if (safeIndex != -1)
+ {
+ TConstantUnion *safeConstantUnion = new TConstantUnion();
+ safeConstantUnion->setIConst(safeIndex);
+ indexConstantUnion->replaceConstantUnion(safeConstantUnion);
+ }
+
indexedExpression = intermediate.addIndex(EOpIndexDirect, baseExpression, indexExpression, location);
}
}