Commit abb0c381 by Olli Etuaho

Check that layout qualifiers may only appear in declarations

In the shading language grammar, layout qualifiers may appear in loop conditions and function declarations, but this is not valid ESSL 3.00 according to section 4.3.8. TEST=angle_unittests, dEQP-GLES3.functional.shaders.*layout* BUG=angleproject:1064 Change-Id: I73f805247bf6678b953f2e1d45a23391e9eacb96 Reviewed-on: https://chromium-review.googlesource.com/285040Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent 8e17a496
...@@ -1376,6 +1376,13 @@ TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, bool inva ...@@ -1376,6 +1376,13 @@ TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, bool inva
} }
else else
{ {
if (!layoutQualifier.isEmpty())
{
if (globalErrorCheck(typeSpecifier.line, symbolTable.atGlobalLevel(), "layout"))
{
recover();
}
}
switch (qualifier) switch (qualifier)
{ {
case EvqSmoothIn: case EvqSmoothIn:
......
...@@ -759,10 +759,16 @@ function_header_with_parameters ...@@ -759,10 +759,16 @@ function_header_with_parameters
function_header function_header
: fully_specified_type IDENTIFIER LEFT_PAREN { : fully_specified_type IDENTIFIER LEFT_PAREN {
if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary) { if ($1.qualifier != EvqGlobal && $1.qualifier != EvqTemporary)
{
context->error(@2, "no qualifiers allowed for function return", getQualifierString($1.qualifier)); context->error(@2, "no qualifiers allowed for function return", getQualifierString($1.qualifier));
context->recover(); context->recover();
} }
if (!$1.layoutQualifier.isEmpty())
{
context->error(@2, "no qualifiers allowed for function return", "layout");
context->recover();
}
// make sure a sampler is not involved as well... // make sure a sampler is not involved as well...
if (context->samplerErrorCheck(@2, $1, "samplers can't be function return values")) if (context->samplerErrorCheck(@2, $1, "samplers can't be function return values"))
context->recover(); context->recover();
......
...@@ -694,34 +694,34 @@ static const yytype_uint8 yytranslate[] = ...@@ -694,34 +694,34 @@ static const yytype_uint8 yytranslate[] =
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] = static const yytype_uint16 yyrline[] =
{ {
0, 211, 211, 212, 215, 239, 242, 247, 252, 257, 0, 212, 212, 213, 216, 240, 243, 248, 253, 258,
262, 268, 271, 274, 277, 280, 283, 289, 297, 308, 263, 269, 272, 275, 278, 281, 284, 290, 298, 309,
312, 320, 323, 329, 333, 340, 346, 355, 363, 369, 313, 321, 324, 330, 334, 341, 347, 356, 364, 370,
376, 386, 389, 392, 395, 405, 406, 407, 408, 416, 377, 387, 390, 393, 396, 406, 407, 408, 409, 417,
417, 420, 423, 430, 431, 434, 440, 441, 445, 452, 418, 421, 424, 431, 432, 435, 441, 442, 446, 453,
453, 456, 459, 462, 468, 469, 472, 478, 479, 486, 454, 457, 460, 463, 469, 470, 473, 479, 480, 487,
487, 494, 495, 502, 503, 509, 510, 516, 517, 523, 488, 495, 496, 503, 504, 510, 511, 517, 518, 524,
524, 530, 531, 539, 540, 541, 542, 546, 547, 548, 525, 531, 532, 540, 541, 542, 543, 547, 548, 549,
552, 556, 560, 564, 571, 574, 585, 593, 601, 629, 553, 557, 561, 565, 572, 575, 586, 594, 602, 630,
635, 646, 650, 654, 658, 665, 721, 724, 731, 739, 636, 647, 651, 655, 659, 666, 722, 725, 732, 740,
760, 781, 791, 819, 824, 834, 839, 849, 852, 855, 761, 788, 798, 826, 831, 841, 846, 856, 859, 862,
858, 864, 871, 874, 878, 882, 887, 892, 899, 903, 865, 871, 878, 881, 885, 889, 894, 899, 906, 910,
907, 911, 916, 921, 925, 932, 942, 948, 951, 957, 914, 918, 923, 928, 932, 939, 949, 955, 958, 964,
963, 970, 979, 989, 997, 1000, 1007, 1011, 1015, 1020, 970, 977, 986, 996, 1004, 1007, 1014, 1018, 1022, 1027,
1028, 1031, 1035, 1039, 1048, 1057, 1065, 1075, 1087, 1090, 1035, 1038, 1042, 1046, 1055, 1064, 1072, 1082, 1094, 1097,
1093, 1099, 1106, 1109, 1115, 1118, 1121, 1127, 1130, 1135, 1100, 1106, 1113, 1116, 1122, 1125, 1128, 1134, 1137, 1142,
1150, 1154, 1158, 1162, 1166, 1170, 1175, 1180, 1185, 1190, 1157, 1161, 1165, 1169, 1173, 1177, 1182, 1187, 1192, 1197,
1195, 1200, 1205, 1210, 1215, 1220, 1225, 1230, 1235, 1240, 1202, 1207, 1212, 1217, 1222, 1227, 1232, 1237, 1242, 1247,
1245, 1250, 1255, 1260, 1265, 1270, 1275, 1279, 1283, 1287, 1252, 1257, 1262, 1267, 1272, 1277, 1282, 1286, 1290, 1294,
1291, 1295, 1299, 1303, 1307, 1311, 1315, 1319, 1323, 1327, 1298, 1302, 1306, 1310, 1314, 1318, 1322, 1326, 1330, 1334,
1331, 1335, 1343, 1351, 1355, 1368, 1368, 1371, 1371, 1377, 1338, 1342, 1350, 1358, 1362, 1375, 1375, 1378, 1378, 1384,
1380, 1396, 1399, 1408, 1412, 1418, 1425, 1440, 1444, 1448, 1387, 1403, 1406, 1415, 1419, 1425, 1432, 1447, 1451, 1455,
1449, 1455, 1456, 1457, 1458, 1459, 1460, 1461, 1465, 1466, 1456, 1462, 1463, 1464, 1465, 1466, 1467, 1468, 1472, 1473,
1466, 1466, 1476, 1477, 1481, 1481, 1482, 1482, 1487, 1490, 1473, 1473, 1483, 1484, 1488, 1488, 1489, 1489, 1494, 1497,
1500, 1503, 1509, 1510, 1514, 1522, 1526, 1533, 1533, 1540, 1507, 1510, 1516, 1517, 1521, 1529, 1533, 1540, 1540, 1547,
1543, 1550, 1555, 1570, 1570, 1575, 1575, 1582, 1582, 1590, 1550, 1557, 1562, 1577, 1577, 1582, 1582, 1589, 1589, 1597,
1593, 1599, 1602, 1608, 1612, 1619, 1622, 1625, 1628, 1631, 1600, 1606, 1609, 1615, 1619, 1626, 1629, 1632, 1635, 1638,
1640, 1644, 1651, 1654, 1660, 1660 1647, 1651, 1658, 1661, 1667, 1667
}; };
#endif #endif
...@@ -3273,10 +3273,16 @@ yyreduce: ...@@ -3273,10 +3273,16 @@ yyreduce:
case 100: case 100:
{ {
if ((yyvsp[-2].interm.type).qualifier != EvqGlobal && (yyvsp[-2].interm.type).qualifier != EvqTemporary) { if ((yyvsp[-2].interm.type).qualifier != EvqGlobal && (yyvsp[-2].interm.type).qualifier != EvqTemporary)
{
context->error((yylsp[-1]), "no qualifiers allowed for function return", getQualifierString((yyvsp[-2].interm.type).qualifier)); context->error((yylsp[-1]), "no qualifiers allowed for function return", getQualifierString((yyvsp[-2].interm.type).qualifier));
context->recover(); context->recover();
} }
if (!(yyvsp[-2].interm.type).layoutQualifier.isEmpty())
{
context->error((yylsp[-1]), "no qualifiers allowed for function return", "layout");
context->recover();
}
// make sure a sampler is not involved as well... // make sure a sampler is not involved as well...
if (context->samplerErrorCheck((yylsp[-1]), (yyvsp[-2].interm.type), "samplers can't be function return values")) if (context->samplerErrorCheck((yylsp[-1]), (yyvsp[-2].interm.type), "samplers can't be function return values"))
context->recover(); context->recover();
......
...@@ -647,3 +647,44 @@ TEST_F(MalformedShaderTest, VersionOnSecondLine) ...@@ -647,3 +647,44 @@ TEST_F(MalformedShaderTest, VersionOnSecondLine)
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog; FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
} }
} }
// Layout qualifier can only appear in global scope (ESSL 3.00 section 4.3.8)
TEST_F(MalformedShaderTest, LayoutQualifierInCondition)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"uniform vec4 u;\n"
"out vec4 my_FragColor;\n"
"void main() {\n"
" int i = 0;\n"
" for (int j = 0; layout(location = 0) bool b = false; ++j) {\n"
" ++i;\n"
" }\n"
" my_FragColor = u;\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
// Layout qualifier can only appear where specified (ESSL 3.00 section 4.3.8)
TEST_F(MalformedShaderTest, LayoutQualifierInFunctionReturnType)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"uniform vec4 u;\n"
"out vec4 my_FragColor;\n"
"layout(location = 0) vec4 foo() {\n"
" return u;\n"
"}\n"
"void main() {\n"
" my_FragColor = foo();\n"
"}\n";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure " << mInfoLog;
}
}
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