Detect redefinition of function name as variable. We were previously already detecting when a variable name was redefined as a function, but not the inverse. The fix involves inserting the unmangled function name into the symbol table. Change-Id: I0efd1309d45f004c8d1c5ceb864e08c2ebe22f1d Reviewed-on: https://swiftshader-review.googlesource.com/16048 Tested-by: Nicolas Capens <nicolascapens@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/OpenGL/compiler/ParseHelper.cpp b/src/OpenGL/compiler/ParseHelper.cpp index 1dbe682..a7d7d01 100644 --- a/src/OpenGL/compiler/ParseHelper.cpp +++ b/src/OpenGL/compiler/ParseHelper.cpp
@@ -1018,7 +1018,7 @@ return false; (*variable) = new TVariable(&identifier, type); - if(!symbolTable.declare(**variable)) + if(!symbolTable.declare(*variable)) { error(line, "redefinition", identifier.c_str()); delete (*variable); @@ -1186,7 +1186,7 @@ { TType type(EbtFloat, EbpUndefined); TVariable *fakeVariable = new TVariable(name, type); - symbolTable.declare(*fakeVariable); + symbolTable.declare(fakeVariable); variable = fakeVariable; } @@ -1203,11 +1203,11 @@ // First find by unmangled name to check whether the function name has been // hidden by a variable name or struct typename. const TSymbol* symbol = symbolTable.find(call->getName(), mShaderVersion, builtIn); - if (symbol == 0) { + if (!symbol || symbol->isFunction()) { symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn); } - if (symbol == 0) { + if (!symbol) { error(line, "no matching overloaded function found", call->getName().c_str()); return nullptr; } @@ -1965,7 +1965,7 @@ // // Insert the parameters with name in the symbol table. // - if(!symbolTable.declare(*variable)) + if(!symbolTable.declare(variable)) { error(location, "redefinition", variable->getName().c_str()); recover(); @@ -2041,10 +2041,16 @@ recover(); } } + else + { + // Insert the unmangled name to detect potential future redefinition as a variable. + TFunction *unmangledFunction = new TFunction(NewPoolTString(function->getName().c_str()), function->getReturnType()); + symbolTable.getOuterLevel()->insertUnmangled(unmangledFunction); + } // We're at the inner scope level of the function's arguments and body statement. // Add the function prototype to the surrounding scope instead. - symbolTable.getOuterLevel()->insert(*function); + symbolTable.getOuterLevel()->insert(function); // // If this is a redeclaration, it could also be a definition, in which case, we want to use the @@ -2344,7 +2350,7 @@ } TSymbol* blockNameSymbol = new TSymbol(&blockName); - if(!symbolTable.declare(*blockNameSymbol)) { + if(!symbolTable.declare(blockNameSymbol)) { error(nameLine, "redefinition", blockName.c_str(), "interface block name"); recover(); } @@ -2423,7 +2429,7 @@ TVariable* fieldVariable = new TVariable(&field->name(), *fieldType); fieldVariable->setQualifier(typeQualifier.qualifier); - if(!symbolTable.declare(*fieldVariable)) { + if(!symbolTable.declare(fieldVariable)) { error(field->line(), "redefinition", field->name().c_str(), "interface block member name"); recover(); } @@ -2438,7 +2444,7 @@ TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false); instanceTypeDef->setQualifier(typeQualifier.qualifier); - if(!symbolTable.declare(*instanceTypeDef)) { + if(!symbolTable.declare(instanceTypeDef)) { error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name"); recover(); } @@ -2972,7 +2978,7 @@ recover(); } TVariable *userTypeDef = new TVariable(structName, *structureType, true); - if(!symbolTable.declare(*userTypeDef)) + if(!symbolTable.declare(userTypeDef)) { error(nameLine, "redefinition", structName->c_str(), "struct"); recover();