Commit 722bfb51 by Olli Etuaho Committed by Commit Bot

Fix detecting duplicate field names in structures

Previously field names that were listed in the first declarator list inside a struct declaration were not checked against each other. BUG=angleproject:2204 TEST=angle_unittests Change-Id: Ibf821d45556f6dfe0223dae673644f6795daf4cb Reviewed-on: https://chromium-review.googlesource.com/739825Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
parent 9088557f
......@@ -4573,19 +4573,39 @@ TField *TParseContext::parseStructArrayDeclarator(TString *identifier,
return new TField(type, identifier, loc);
}
void TParseContext::checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
const TFieldList::const_iterator end,
const TString &name,
const TSourceLoc &location)
{
for (auto fieldIter = begin; fieldIter != end; ++fieldIter)
{
if ((*fieldIter)->name() == name)
{
error(location, "duplicate field name in structure", name.c_str());
}
}
}
TFieldList *TParseContext::addStructFieldList(TFieldList *fields, const TSourceLoc &location)
{
for (TFieldList::const_iterator fieldIter = fields->begin(); fieldIter != fields->end();
++fieldIter)
{
checkDoesNotHaveDuplicateFieldName(fields->begin(), fieldIter, (*fieldIter)->name(),
location);
}
return fields;
}
TFieldList *TParseContext::combineStructFieldLists(TFieldList *processedFields,
const TFieldList *newlyAddedFields,
const TSourceLoc &location)
{
for (TField *field : *newlyAddedFields)
{
for (TField *oldField : *processedFields)
{
if (oldField->name() == field->name())
{
error(location, "duplicate field name in structure", field->name().c_str());
}
}
checkDoesNotHaveDuplicateFieldName(processedFields->begin(), processedFields->end(),
field->name(), location);
processedFields->push_back(field);
}
return processedFields;
......
......@@ -306,6 +306,11 @@ class TParseContext : angle::NonCopyable
unsigned int arraySize,
const TSourceLoc &arraySizeLoc);
void checkDoesNotHaveDuplicateFieldName(const TFieldList::const_iterator begin,
const TFieldList::const_iterator end,
const TString &name,
const TSourceLoc &location);
TFieldList *addStructFieldList(TFieldList *fields, const TSourceLoc &location);
TFieldList *combineStructFieldLists(TFieldList *processedFields,
const TFieldList *newlyAddedFields,
const TSourceLoc &location);
......
......@@ -1187,7 +1187,7 @@ struct_specifier
struct_declaration_list
: struct_declaration {
$$ = $1;
$$ = context->addStructFieldList($1, @1);
}
| struct_declaration_list struct_declaration {
$$ = context->combineStructFieldLists($1, $2, @2);
......
......@@ -4358,7 +4358,7 @@ yyreduce:
case 229:
{
(yyval.interm.fieldList) = (yyvsp[0].interm.fieldList);
(yyval.interm.fieldList) = context->addStructFieldList((yyvsp[0].interm.fieldList), (yylsp[0]));
}
break;
......
......@@ -5172,4 +5172,25 @@ TEST_F(FragmentShaderValidationTest, PartiallyUnsizedArrayOfArraysConstructor)
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << mInfoLog;
}
}
\ No newline at end of file
}
// Test that duplicate field names in a struct declarator list are validated.
TEST_F(FragmentShaderValidationTest, DuplicateFieldNamesInStructDeclaratorList)
{
const std::string &shaderString =
R"(precision mediump float;
struct S {
float f, f;
};
void main()
{
gl_FragColor = vec4(1.0);
})";
if (compile(shaderString))
{
FAIL() << "Shader compilation succeeded, expecting failure:\n" << 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