Disallow multiple function prototypes in ESSL 1.00
The same function can't be declared twice in ESSL 1.00. In ESSL 3.00 this
is allowed.
A function prototype following the definition of that function is not
interpreted as redeclaration, and the shader compiler continues to allow
this.
BUG=angleproject:1067
TEST=angle_unittests,
dEQP-GLES2.functional.shaders.functions.invalid.double_declare*
Change-Id: I6d2ddafd456d378d92839600f19069ad1cd19aff
Reviewed-on: https://chromium-review.googlesource.com/320082
Tryjob-Request: Olli Etuaho <oetuaho@nvidia.com>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/ParseContext.cpp b/src/compiler/translator/ParseContext.cpp
index a51d8a0..89317e8 100644
--- a/src/compiler/translator/ParseContext.cpp
+++ b/src/compiler/translator/ParseContext.cpp
@@ -1928,6 +1928,20 @@
TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &function,
const TSourceLoc &location)
{
+ // Note: symbolTableFunction could be the same as function if this is the first declaration.
+ // Either way the instance in the symbol table is used to track whether the function is declared
+ // multiple times.
+ TFunction *symbolTableFunction =
+ static_cast<TFunction *>(symbolTable.find(function.getMangledName(), getShaderVersion()));
+ if (symbolTableFunction->hasPrototypeDeclaration() && mShaderVersion == 100)
+ {
+ // ESSL 1.00.17 section 4.2.7.
+ // Doesn't apply to ESSL 3.00.4: see section 4.2.3.
+ error(location, "duplicate function prototype declarations are not allowed", "function");
+ recover();
+ }
+ symbolTableFunction->setHasPrototypeDeclaration();
+
TIntermAggregate *prototype = new TIntermAggregate;
prototype->setType(function.getReturnType());
prototype->setName(function.getMangledName());
@@ -2086,12 +2100,12 @@
TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TFunction *function)
{
//
- // Multiple declarations of the same function are allowed.
+ // We don't know at this point whether this is a function definition or a prototype.
+ // The definition production code will check for redefinitions.
+ // In the case of ESSL 1.00 the prototype production code will also check for redeclarations.
//
- // If this is a definition, the definition production code will check for redefinitions
- // (we don't know at this point if it's a definition or not).
- //
- // Redeclarations are allowed. But, return types and parameter qualifiers must match.
+ // Return types and parameter qualifiers must match in all redeclarations, so those are checked
+ // here.
//
TFunction *prevDec =
static_cast<TFunction *>(symbolTable.find(function->getMangledName(), getShaderVersion()));