Ternary selection cleanup
Moved the ternary selection code to TParseContext
where checks were added to make sure arrays and
structs can't use it.
Change-Id: If3c007820870276cdf540005e095d89d54949bc4
Reviewed-on: https://swiftshader-review.googlesource.com/3669
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/compiler/ParseHelper.cpp b/src/OpenGL/compiler/ParseHelper.cpp
index 899bac2..e75f0ba 100644
--- a/src/OpenGL/compiler/ParseHelper.cpp
+++ b/src/OpenGL/compiler/ParseHelper.cpp
@@ -3403,6 +3403,29 @@
return callNode;
}
+TIntermTyped *TParseContext::addTernarySelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &loc)
+{
+ if(boolErrorCheck(loc, cond))
+ recover();
+
+ if(trueBlock->getType() != falseBlock->getType())
+ {
+ binaryOpError(loc, ":", trueBlock->getCompleteString(), falseBlock->getCompleteString());
+ recover();
+ return falseBlock;
+ }
+ // ESSL1 sections 5.2 and 5.7:
+ // ESSL3 section 5.7:
+ // Ternary operator is not among the operators allowed for structures/arrays.
+ if(trueBlock->isArray() || trueBlock->getBasicType() == EbtStruct)
+ {
+ error(loc, "ternary operator is not allowed for structures or arrays", ":");
+ recover();
+ return falseBlock;
+ }
+ return intermediate.addSelection(cond, trueBlock, falseBlock, loc);
+}
+
//
// Parse an array of strings using yyparse.
//
diff --git a/src/OpenGL/compiler/ParseHelper.h b/src/OpenGL/compiler/ParseHelper.h
index 145d3f7..52a644e 100644
--- a/src/OpenGL/compiler/ParseHelper.h
+++ b/src/OpenGL/compiler/ParseHelper.h
@@ -223,6 +223,8 @@
TIntermTyped *addFunctionCallOrMethod(TFunction *fnCall, TIntermNode *paramNode, TIntermNode *thisNode, const TSourceLoc &loc, bool *fatalError);
+ TIntermTyped *addTernarySelection(TIntermTyped *cond, TIntermTyped *trueBlock, TIntermTyped *falseBlock, const TSourceLoc &line);
+
private:
bool declareVariable(const TSourceLoc &line, const TString &identifier, const TType &type, TVariable **variable);
diff --git a/src/OpenGL/compiler/glslang.y b/src/OpenGL/compiler/glslang.y
index b591ee5..daeb4e7 100644
--- a/src/OpenGL/compiler/glslang.y
+++ b/src/OpenGL/compiler/glslang.y
@@ -293,11 +293,11 @@
function_call
: function_call_or_method {
- bool fatalError = false;
- $$ = context->addFunctionCallOrMethod($1.function, $1.intermNode, nullptr, @1, &fatalError);
- if (fatalError)
+ bool fatalError = false;
+ $$ = context->addFunctionCallOrMethod($1.function, $1.intermNode, nullptr, @1, &fatalError);
+ if (fatalError)
{
- YYERROR;
+ YYERROR;
}
}
;
@@ -550,18 +550,7 @@
conditional_expression
: logical_or_expression { $$ = $1; }
| logical_or_expression QUESTION expression COLON assignment_expression {
- if (context->boolErrorCheck(@2, $1))
- context->recover();
-
- $$ = context->intermediate.addSelection($1, $3, $5, @2);
- if ($3->getType() != $5->getType())
- $$ = 0;
-
- if ($$ == 0) {
- context->binaryOpError(@2, ":", $3->getCompleteString(), $5->getCompleteString());
- context->recover();
- $$ = $5;
- }
+ $$ = context->addTernarySelection($1, $3, $5, @2);
}
;
diff --git a/src/OpenGL/compiler/glslang_tab.cpp b/src/OpenGL/compiler/glslang_tab.cpp
index 9ecc6aa..01272ff 100644
--- a/src/OpenGL/compiler/glslang_tab.cpp
+++ b/src/OpenGL/compiler/glslang_tab.cpp
@@ -771,28 +771,28 @@
388, 398, 408, 430, 431, 432, 433, 441, 442, 446,
450, 458, 459, 462, 468, 469, 473, 480, 481, 484,
487, 490, 496, 497, 500, 506, 507, 514, 515, 522,
- 523, 530, 531, 537, 538, 544, 545, 551, 552, 569,
- 570, 578, 579, 580, 581, 583, 584, 585, 587, 589,
- 591, 593, 598, 601, 612, 620, 628, 655, 661, 668,
- 672, 676, 680, 687, 725, 728, 735, 743, 764, 785,
- 796, 825, 830, 840, 845, 855, 858, 861, 864, 870,
- 877, 880, 884, 888, 893, 898, 905, 909, 913, 917,
- 922, 927, 931, 1007, 1017, 1023, 1026, 1032, 1038, 1045,
- 1054, 1063, 1066, 1069, 1076, 1080, 1087, 1091, 1096, 1101,
- 1111, 1121, 1130, 1140, 1147, 1150, 1153, 1159, 1166, 1169,
- 1175, 1178, 1181, 1187, 1190, 1195, 1210, 1214, 1218, 1222,
- 1226, 1230, 1235, 1240, 1245, 1250, 1255, 1260, 1265, 1270,
- 1275, 1280, 1285, 1290, 1296, 1302, 1308, 1314, 1320, 1326,
- 1332, 1338, 1344, 1349, 1354, 1363, 1368, 1373, 1378, 1383,
- 1388, 1393, 1398, 1403, 1408, 1413, 1418, 1423, 1428, 1433,
- 1446, 1446, 1449, 1449, 1455, 1458, 1474, 1477, 1486, 1490,
- 1496, 1503, 1518, 1522, 1526, 1527, 1533, 1534, 1535, 1536,
- 1537, 1538, 1539, 1543, 1544, 1544, 1544, 1554, 1555, 1559,
- 1559, 1560, 1560, 1565, 1568, 1578, 1581, 1587, 1588, 1592,
- 1600, 1604, 1611, 1611, 1618, 1621, 1630, 1635, 1652, 1652,
- 1657, 1657, 1664, 1664, 1672, 1675, 1681, 1684, 1690, 1694,
- 1701, 1704, 1707, 1710, 1713, 1722, 1726, 1733, 1736, 1742,
- 1742
+ 523, 530, 531, 537, 538, 544, 545, 551, 552, 558,
+ 559, 567, 568, 569, 570, 572, 573, 574, 576, 578,
+ 580, 582, 587, 590, 601, 609, 617, 644, 650, 657,
+ 661, 665, 669, 676, 714, 717, 724, 732, 753, 774,
+ 785, 814, 819, 829, 834, 844, 847, 850, 853, 859,
+ 866, 869, 873, 877, 882, 887, 894, 898, 902, 906,
+ 911, 916, 920, 996, 1006, 1012, 1015, 1021, 1027, 1034,
+ 1043, 1052, 1055, 1058, 1065, 1069, 1076, 1080, 1085, 1090,
+ 1100, 1110, 1119, 1129, 1136, 1139, 1142, 1148, 1155, 1158,
+ 1164, 1167, 1170, 1176, 1179, 1184, 1199, 1203, 1207, 1211,
+ 1215, 1219, 1224, 1229, 1234, 1239, 1244, 1249, 1254, 1259,
+ 1264, 1269, 1274, 1279, 1285, 1291, 1297, 1303, 1309, 1315,
+ 1321, 1327, 1333, 1338, 1343, 1352, 1357, 1362, 1367, 1372,
+ 1377, 1382, 1387, 1392, 1397, 1402, 1407, 1412, 1417, 1422,
+ 1435, 1435, 1438, 1438, 1444, 1447, 1463, 1466, 1475, 1479,
+ 1485, 1492, 1507, 1511, 1515, 1516, 1522, 1523, 1524, 1525,
+ 1526, 1527, 1528, 1532, 1533, 1533, 1533, 1543, 1544, 1548,
+ 1548, 1549, 1549, 1554, 1557, 1567, 1570, 1576, 1577, 1581,
+ 1589, 1593, 1600, 1600, 1607, 1610, 1619, 1624, 1641, 1641,
+ 1646, 1646, 1653, 1653, 1661, 1664, 1670, 1673, 1679, 1683,
+ 1690, 1693, 1696, 1699, 1702, 1711, 1715, 1722, 1725, 1731,
+ 1731
};
#endif
@@ -3026,18 +3026,7 @@
case 68:
{
- if (context->boolErrorCheck((yylsp[(2) - (5)]), (yyvsp[(1) - (5)].interm.intermTypedNode)))
- context->recover();
-
- (yyval.interm.intermTypedNode) = context->intermediate.addSelection((yyvsp[(1) - (5)].interm.intermTypedNode), (yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.intermTypedNode), (yylsp[(2) - (5)]));
- if ((yyvsp[(3) - (5)].interm.intermTypedNode)->getType() != (yyvsp[(5) - (5)].interm.intermTypedNode)->getType())
- (yyval.interm.intermTypedNode) = 0;
-
- if ((yyval.interm.intermTypedNode) == 0) {
- context->binaryOpError((yylsp[(2) - (5)]), ":", (yyvsp[(3) - (5)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(5) - (5)].interm.intermTypedNode)->getCompleteString());
- context->recover();
- (yyval.interm.intermTypedNode) = (yyvsp[(5) - (5)].interm.intermTypedNode);
- }
+ (yyval.interm.intermTypedNode) = context->addTernarySelection((yyvsp[(1) - (5)].interm.intermTypedNode), (yyvsp[(3) - (5)].interm.intermTypedNode), (yyvsp[(5) - (5)].interm.intermTypedNode), (yylsp[(2) - (5)]));
}
break;