Commit d6b14287 by Olli Etuaho

Move binary op array check to ParseContext

Also piece together an addAssign function in ParseContext that uses the binary op array check. This will make it easier to change the array-related checks in the future to use shaderVersion. Moving validation out from IntermBinary::promote also makes the architecture clearer, promote()'s role should be mainly to determine the type of the return value of the binary operation, not to do validation. BUG=angleproject:941 TEST=angle_unittests, WebGL conformance tests Change-Id: If1de33ea250893527be7f0d7930d4678a0864684 Reviewed-on: https://chromium-review.googlesource.com/260571Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com>
parent b2983c95
...@@ -388,12 +388,7 @@ bool TIntermUnary::promote(TInfoSink &) ...@@ -388,12 +388,7 @@ bool TIntermUnary::promote(TInfoSink &)
bool TIntermBinary::promote(TInfoSink &infoSink) bool TIntermBinary::promote(TInfoSink &infoSink)
{ {
// This function only handles scalars, vectors, and matrices. // This function only handles scalars, vectors, and matrices.
if (mLeft->isArray() || mRight->isArray()) ASSERT(!mLeft->isArray() && !mRight->isArray());
{
infoSink.info.message(EPrefixInternalError, getLine(),
"Invalid operation for arrays");
return false;
}
// GLSL ES 2.0 does not support implicit type casting. // GLSL ES 2.0 does not support implicit type casting.
// So the basic type should usually match. // So the basic type should usually match.
......
...@@ -1198,7 +1198,7 @@ bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& id ...@@ -1198,7 +1198,7 @@ bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& id
if (qualifier != EvqConst) { if (qualifier != EvqConst) {
TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line); TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line); intermNode = createAssign(EOpInitialize, intermSymbol, initializer, line);
if (intermNode == 0) { if (intermNode == 0) {
assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
return true; return true;
...@@ -2716,21 +2716,34 @@ TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *chil ...@@ -2716,21 +2716,34 @@ TIntermTyped *TParseContext::addUnaryMathLValue(TOperator op, TIntermTyped *chil
return addUnaryMath(op, child, loc); return addUnaryMath(op, child, loc);
} }
bool TParseContext::binaryOpArrayCheck(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc)
{
if (left->isArray() || right->isArray())
{
error(loc, "Invalid operation for arrays", GetOperatorString(op));
return false;
}
return true;
}
TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right, TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc) const TSourceLoc &loc)
{ {
if (!binaryOpArrayCheck(op, left, right, loc))
return nullptr;
switch (op) switch (op)
{ {
case EOpEqual: case EOpEqual:
case EOpNotEqual: case EOpNotEqual:
if (left->isArray())
return nullptr;
break; break;
case EOpLessThan: case EOpLessThan:
case EOpGreaterThan: case EOpGreaterThan:
case EOpLessThanEqual: case EOpLessThanEqual:
case EOpGreaterThanEqual: case EOpGreaterThanEqual:
if (left->isMatrix() || left->isArray() || left->isVector() || ASSERT(!left->isArray() && !right->isArray());
if (left->isMatrix() || left->isVector() ||
left->getBasicType() == EbtStruct) left->getBasicType() == EbtStruct)
{ {
return nullptr; return nullptr;
...@@ -2739,8 +2752,9 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *l ...@@ -2739,8 +2752,9 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *l
case EOpLogicalOr: case EOpLogicalOr:
case EOpLogicalXor: case EOpLogicalXor:
case EOpLogicalAnd: case EOpLogicalAnd:
ASSERT(!left->isArray() && !right->isArray());
if (left->getBasicType() != EbtBool || if (left->getBasicType() != EbtBool ||
left->isMatrix() || left->isArray() || left->isVector()) left->isMatrix() || left->isVector())
{ {
return nullptr; return nullptr;
} }
...@@ -2749,12 +2763,14 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *l ...@@ -2749,12 +2763,14 @@ TIntermTyped *TParseContext::addBinaryMathInternal(TOperator op, TIntermTyped *l
case EOpSub: case EOpSub:
case EOpDiv: case EOpDiv:
case EOpMul: case EOpMul:
ASSERT(!left->isArray() && !right->isArray());
if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool) if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool)
{ {
return nullptr; return nullptr;
} }
break; break;
case EOpIMod: case EOpIMod:
ASSERT(!left->isArray() && !right->isArray());
// Note that this is only for the % operator, not for mod() // Note that this is only for the % operator, not for mod()
if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat) if (left->getBasicType() == EbtStruct || left->getBasicType() == EbtBool || left->getBasicType() == EbtFloat)
{ {
...@@ -2804,6 +2820,29 @@ TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, TIntermTyp ...@@ -2804,6 +2820,29 @@ TIntermTyped *TParseContext::addBinaryMathBooleanResult(TOperator op, TIntermTyp
return node; return node;
} }
TIntermTyped *TParseContext::createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc)
{
if (binaryOpArrayCheck(op, left, right, loc))
{
return intermediate.addAssign(op, left, right, loc);
}
return nullptr;
}
TIntermTyped *TParseContext::addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc)
{
TIntermTyped *node = createAssign(op, left, right, loc);
if (node == nullptr)
{
assignError(loc, "assign", left->getCompleteString(), right->getCompleteString());
recover();
return left;
}
return node;
}
TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc) TIntermBranch *TParseContext::addBranch(TOperator op, const TSourceLoc &loc)
{ {
switch (op) switch (op)
......
...@@ -177,6 +177,8 @@ struct TParseContext { ...@@ -177,6 +177,8 @@ struct TParseContext {
const TSourceLoc &); const TSourceLoc &);
TIntermTyped *addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right, TIntermTyped *addBinaryMathBooleanResult(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &); const TSourceLoc &);
TIntermTyped *addAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc);
TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc); TIntermBranch *addBranch(TOperator op, const TSourceLoc &loc);
TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc); TIntermBranch *addBranch(TOperator op, TIntermTyped *returnValue, const TSourceLoc &loc);
...@@ -187,6 +189,12 @@ struct TParseContext { ...@@ -187,6 +189,12 @@ struct TParseContext {
private: private:
TIntermTyped *addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right, TIntermTyped *addBinaryMathInternal(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc); const TSourceLoc &loc);
TIntermTyped *createAssign(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc);
// Return true if array-related checks pass
bool binaryOpArrayCheck(TOperator op, TIntermTyped *left, TIntermTyped *right,
const TSourceLoc &loc);
}; };
int PaParseStrings(size_t count, const char* const string[], const int length[], int PaParseStrings(size_t count, const char* const string[], const int length[],
......
...@@ -536,12 +536,7 @@ assignment_expression ...@@ -536,12 +536,7 @@ assignment_expression
| unary_expression assignment_operator assignment_expression { | unary_expression assignment_operator assignment_expression {
if (context->lValueErrorCheck(@2, "assign", $1)) if (context->lValueErrorCheck(@2, "assign", $1))
context->recover(); context->recover();
$$ = context->intermediate.addAssign($2.op, $1, $3, @2); $$ = context->addAssign($2.op, $1, $3, @2);
if ($$ == 0) {
context->assignError(@2, "assign", $1->getCompleteString(), $3->getCompleteString());
context->recover();
$$ = $1;
}
} }
; ;
......
...@@ -696,27 +696,27 @@ static const yytype_uint16 yyrline[] = ...@@ -696,27 +696,27 @@ static const yytype_uint16 yyrline[] =
411, 414, 417, 424, 425, 428, 434, 435, 439, 446, 411, 414, 417, 424, 425, 428, 434, 435, 439, 446,
447, 450, 453, 456, 462, 463, 466, 472, 473, 480, 447, 450, 453, 456, 462, 463, 466, 472, 473, 480,
481, 488, 489, 496, 497, 503, 504, 510, 511, 517, 481, 488, 489, 496, 497, 503, 504, 510, 511, 517,
518, 535, 536, 549, 550, 551, 552, 556, 557, 558, 518, 535, 536, 544, 545, 546, 547, 551, 552, 553,
562, 566, 570, 574, 581, 584, 595, 603, 611, 638, 557, 561, 565, 569, 576, 579, 590, 598, 606, 633,
644, 655, 659, 663, 667, 674, 730, 733, 740, 748, 639, 650, 654, 658, 662, 669, 725, 728, 735, 743,
769, 790, 800, 828, 833, 843, 848, 858, 861, 864, 764, 785, 795, 823, 828, 838, 843, 853, 856, 859,
867, 873, 880, 883, 887, 891, 895, 902, 906, 910, 862, 868, 875, 878, 882, 886, 890, 897, 901, 905,
917, 921, 925, 932, 941, 947, 950, 956, 962, 969, 912, 916, 920, 927, 936, 942, 945, 951, 957, 964,
978, 987, 995, 998, 1005, 1009, 1016, 1019, 1023, 1027, 973, 982, 990, 993, 1000, 1004, 1011, 1014, 1018, 1022,
1036, 1045, 1053, 1063, 1075, 1078, 1081, 1087, 1094, 1097, 1031, 1040, 1048, 1058, 1070, 1073, 1076, 1082, 1089, 1092,
1103, 1106, 1109, 1115, 1118, 1133, 1137, 1141, 1145, 1149, 1098, 1101, 1104, 1110, 1113, 1128, 1132, 1136, 1140, 1144,
1153, 1158, 1163, 1168, 1173, 1178, 1183, 1188, 1193, 1198, 1148, 1153, 1158, 1163, 1168, 1173, 1178, 1183, 1188, 1193,
1203, 1208, 1213, 1218, 1223, 1228, 1233, 1238, 1243, 1248, 1198, 1203, 1208, 1213, 1218, 1223, 1228, 1233, 1238, 1243,
1253, 1258, 1262, 1266, 1270, 1274, 1278, 1282, 1286, 1290, 1248, 1253, 1257, 1261, 1265, 1269, 1273, 1277, 1281, 1285,
1294, 1298, 1302, 1306, 1310, 1314, 1318, 1326, 1334, 1338, 1289, 1293, 1297, 1301, 1305, 1309, 1313, 1321, 1329, 1333,
1351, 1351, 1354, 1354, 1360, 1363, 1379, 1382, 1391, 1395, 1346, 1346, 1349, 1349, 1355, 1358, 1374, 1377, 1386, 1390,
1401, 1408, 1423, 1427, 1431, 1432, 1438, 1439, 1440, 1441, 1396, 1403, 1418, 1422, 1426, 1427, 1433, 1434, 1435, 1436,
1442, 1443, 1444, 1448, 1449, 1449, 1449, 1459, 1460, 1464, 1437, 1438, 1439, 1443, 1444, 1444, 1444, 1454, 1455, 1459,
1464, 1465, 1465, 1470, 1473, 1483, 1486, 1492, 1493, 1497, 1459, 1460, 1460, 1465, 1468, 1478, 1481, 1487, 1488, 1492,
1505, 1509, 1516, 1516, 1523, 1526, 1533, 1538, 1555, 1555, 1500, 1504, 1511, 1511, 1518, 1521, 1528, 1533, 1550, 1550,
1560, 1560, 1567, 1567, 1575, 1578, 1584, 1587, 1593, 1597, 1555, 1555, 1562, 1562, 1570, 1573, 1579, 1582, 1588, 1592,
1604, 1607, 1610, 1613, 1616, 1625, 1629, 1636, 1639, 1645, 1599, 1602, 1605, 1608, 1611, 1620, 1624, 1631, 1634, 1640,
1645 1640
}; };
#endif #endif
...@@ -2897,12 +2897,7 @@ yyreduce: ...@@ -2897,12 +2897,7 @@ yyreduce:
{ {
if (context->lValueErrorCheck((yylsp[-1]), "assign", (yyvsp[-2].interm.intermTypedNode))) if (context->lValueErrorCheck((yylsp[-1]), "assign", (yyvsp[-2].interm.intermTypedNode)))
context->recover(); context->recover();
(yyval.interm.intermTypedNode) = context->intermediate.addAssign((yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1])); (yyval.interm.intermTypedNode) = context->addAssign((yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yylsp[-1]));
if ((yyval.interm.intermTypedNode) == 0) {
context->assignError((yylsp[-1]), "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString());
context->recover();
(yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode);
}
} }
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment