Commit 0b7471ab by Nicolas Capens Committed by Nicolas Capens

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/16048Tested-by: 's avatarNicolas Capens <nicolascapens@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent c67e57e9
...@@ -427,10 +427,10 @@ void InsertBuiltInFunctions(GLenum type, const ShBuiltInResources &resources, TS ...@@ -427,10 +427,10 @@ void InsertBuiltInFunctions(GLenum type, const ShBuiltInResources &resources, TS
fields->push_back(diff); fields->push_back(diff);
TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields); TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields);
TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true); TVariable *depthRangeParameters = new TVariable(&depthRangeStruct->name(), depthRangeStruct, true);
symbolTable.insert(COMMON_BUILTINS, *depthRangeParameters); symbolTable.insert(COMMON_BUILTINS, depthRangeParameters);
TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct)); TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(depthRangeStruct));
depthRange->setQualifier(EvqUniform); depthRange->setQualifier(EvqUniform);
symbolTable.insert(COMMON_BUILTINS, *depthRange); symbolTable.insert(COMMON_BUILTINS, depthRange);
// //
// Implementation dependent built-in constants. // Implementation dependent built-in constants.
...@@ -460,18 +460,18 @@ void IdentifyBuiltIns(GLenum shaderType, ...@@ -460,18 +460,18 @@ void IdentifyBuiltIns(GLenum shaderType,
switch(shaderType) switch(shaderType)
{ {
case GL_FRAGMENT_SHADER: case GL_FRAGMENT_SHADER:
symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4))); symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FragCoord"), TType(EbtFloat, EbpMedium, EvqFragCoord, 4)));
symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1))); symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2))); symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointCoord"), TType(EbtFloat, EbpMedium, EvqPointCoord, 2)));
symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4))); symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragColor"), TType(EbtFloat, EbpMedium, EvqFragColor, 4)));
symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4))); symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EbpHigh, EvqFragDepth, 1))); symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
break; break;
case GL_VERTEX_SHADER: case GL_VERTEX_SHADER:
symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4))); symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_Position"), TType(EbtFloat, EbpHigh, EvqPosition, 4)));
symbolTable.insert(COMMON_BUILTINS, *new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1))); symbolTable.insert(COMMON_BUILTINS, new TVariable(NewPoolTString("gl_PointSize"), TType(EbtFloat, EbpMedium, EvqPointSize, 1)));
symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1))); symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_InstanceID"), TType(EbtInt, EbpHigh, EvqInstanceID, 1)));
symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_VertexID"), TType(EbtInt, EbpHigh, EvqVertexID, 1))); symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_VertexID"), TType(EbtInt, EbpHigh, EvqVertexID, 1)));
break; break;
default: assert(false && "Language not supported"); default: assert(false && "Language not supported");
} }
...@@ -484,7 +484,7 @@ void IdentifyBuiltIns(GLenum shaderType, ...@@ -484,7 +484,7 @@ void IdentifyBuiltIns(GLenum shaderType,
// Set up gl_FragData. The array size. // Set up gl_FragData. The array size.
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true); TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
fragData.setArraySize(resources.MaxDrawBuffers); fragData.setArraySize(resources.MaxDrawBuffers);
symbolTable.insert(ESSL1_BUILTINS, *new TVariable(NewPoolTString("gl_FragData"), fragData)); symbolTable.insert(ESSL1_BUILTINS, new TVariable(NewPoolTString("gl_FragData"), fragData));
} }
break; break;
default: break; default: break;
......
...@@ -1018,7 +1018,7 @@ bool TParseContext::declareVariable(const TSourceLoc &line, const TString &ident ...@@ -1018,7 +1018,7 @@ bool TParseContext::declareVariable(const TSourceLoc &line, const TString &ident
return false; return false;
(*variable) = new TVariable(&identifier, type); (*variable) = new TVariable(&identifier, type);
if(!symbolTable.declare(**variable)) if(!symbolTable.declare(*variable))
{ {
error(line, "redefinition", identifier.c_str()); error(line, "redefinition", identifier.c_str());
delete (*variable); delete (*variable);
...@@ -1186,7 +1186,7 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location, ...@@ -1186,7 +1186,7 @@ const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
{ {
TType type(EbtFloat, EbpUndefined); TType type(EbtFloat, EbpUndefined);
TVariable *fakeVariable = new TVariable(name, type); TVariable *fakeVariable = new TVariable(name, type);
symbolTable.declare(*fakeVariable); symbolTable.declare(fakeVariable);
variable = fakeVariable; variable = fakeVariable;
} }
...@@ -1203,11 +1203,11 @@ const TFunction* TParseContext::findFunction(const TSourceLoc &line, TFunction* ...@@ -1203,11 +1203,11 @@ const TFunction* TParseContext::findFunction(const TSourceLoc &line, TFunction*
// First find by unmangled name to check whether the function name has been // First find by unmangled name to check whether the function name has been
// hidden by a variable name or struct typename. // hidden by a variable name or struct typename.
const TSymbol* symbol = symbolTable.find(call->getName(), mShaderVersion, builtIn); const TSymbol* symbol = symbolTable.find(call->getName(), mShaderVersion, builtIn);
if (symbol == 0) { if (!symbol || symbol->isFunction()) {
symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn); symbol = symbolTable.find(call->getMangledName(), mShaderVersion, builtIn);
} }
if (symbol == 0) { if (!symbol) {
error(line, "no matching overloaded function found", call->getName().c_str()); error(line, "no matching overloaded function found", call->getName().c_str());
return nullptr; return nullptr;
} }
...@@ -1965,7 +1965,7 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location, TFunction ...@@ -1965,7 +1965,7 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location, TFunction
// //
// Insert the parameters with name in the symbol table. // Insert the parameters with name in the symbol table.
// //
if(!symbolTable.declare(*variable)) if(!symbolTable.declare(variable))
{ {
error(location, "redefinition", variable->getName().c_str()); error(location, "redefinition", variable->getName().c_str());
recover(); recover();
...@@ -2041,10 +2041,16 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF ...@@ -2041,10 +2041,16 @@ TFunction *TParseContext::parseFunctionDeclarator(const TSourceLoc &location, TF
recover(); 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. // We're at the inner scope level of the function's arguments and body statement.
// Add the function prototype to the surrounding scope instead. // 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 // If this is a redeclaration, it could also be a definition, in which case, we want to use the
...@@ -2344,7 +2350,7 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif ...@@ -2344,7 +2350,7 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif
} }
TSymbol* blockNameSymbol = new TSymbol(&blockName); TSymbol* blockNameSymbol = new TSymbol(&blockName);
if(!symbolTable.declare(*blockNameSymbol)) { if(!symbolTable.declare(blockNameSymbol)) {
error(nameLine, "redefinition", blockName.c_str(), "interface block name"); error(nameLine, "redefinition", blockName.c_str(), "interface block name");
recover(); recover();
} }
...@@ -2423,7 +2429,7 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif ...@@ -2423,7 +2429,7 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif
TVariable* fieldVariable = new TVariable(&field->name(), *fieldType); TVariable* fieldVariable = new TVariable(&field->name(), *fieldType);
fieldVariable->setQualifier(typeQualifier.qualifier); fieldVariable->setQualifier(typeQualifier.qualifier);
if(!symbolTable.declare(*fieldVariable)) { if(!symbolTable.declare(fieldVariable)) {
error(field->line(), "redefinition", field->name().c_str(), "interface block member name"); error(field->line(), "redefinition", field->name().c_str(), "interface block member name");
recover(); recover();
} }
...@@ -2438,7 +2444,7 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif ...@@ -2438,7 +2444,7 @@ TIntermAggregate* TParseContext::addInterfaceBlock(const TPublicType& typeQualif
TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false); TVariable* instanceTypeDef = new TVariable(instanceName, interfaceBlockType, false);
instanceTypeDef->setQualifier(typeQualifier.qualifier); instanceTypeDef->setQualifier(typeQualifier.qualifier);
if(!symbolTable.declare(*instanceTypeDef)) { if(!symbolTable.declare(instanceTypeDef)) {
error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name"); error(instanceLine, "redefinition", instanceName->c_str(), "interface block instance name");
recover(); recover();
} }
...@@ -2972,7 +2978,7 @@ TPublicType TParseContext::addStructure(const TSourceLoc &structLine, const TSou ...@@ -2972,7 +2978,7 @@ TPublicType TParseContext::addStructure(const TSourceLoc &structLine, const TSou
recover(); recover();
} }
TVariable *userTypeDef = new TVariable(structName, *structureType, true); TVariable *userTypeDef = new TVariable(structName, *structureType, true);
if(!symbolTable.declare(*userTypeDef)) if(!symbolTable.declare(userTypeDef))
{ {
error(nameLine, "redefinition", structName->c_str(), "struct"); error(nameLine, "redefinition", structName->c_str(), "struct");
recover(); recover();
......
...@@ -27,8 +27,8 @@ ...@@ -27,8 +27,8 @@
#include <limits.h> #include <limits.h>
#include <algorithm> #include <algorithm>
#if defined(_MSC_VER) && MSC_VER < 1900 #if defined(_MSC_VER) && MSC_VER < 1900
#define snprintf _snprintf #define snprintf _snprintf
#endif #endif
int TSymbolTableLevel::uniqueId = 0; int TSymbolTableLevel::uniqueId = 0;
...@@ -195,6 +195,35 @@ TSymbolTableLevel::~TSymbolTableLevel() ...@@ -195,6 +195,35 @@ TSymbolTableLevel::~TSymbolTableLevel()
delete (*it).second; delete (*it).second;
} }
bool TSymbolTableLevel::insert(TSymbol *symbol)
{
symbol->setUniqueId(nextUniqueId());
// returning true means symbol was added to the table
tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
return result.second;
}
bool TSymbolTableLevel::insertUnmangled(TFunction *function)
{
function->setUniqueId(nextUniqueId());
// returning true means symbol was added to the table
tInsertResult result = level.insert(tLevelPair(function->getName(), function));
return result.second;
}
TSymbol *TSymbolTableLevel::find(const TString &name) const
{
tLevel::const_iterator it = level.find(name);
if (it == level.end())
return 0;
else
return (*it).second;
}
TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
{ {
int level = currentLevel(); int level = currentLevel();
......
...@@ -206,27 +206,12 @@ public: ...@@ -206,27 +206,12 @@ public:
TSymbolTableLevel() { } TSymbolTableLevel() { }
~TSymbolTableLevel(); ~TSymbolTableLevel();
bool insert(TSymbol &symbol) bool insert(TSymbol *symbol);
{
symbol.setUniqueId(nextUniqueId());
//
// returning true means symbol was added to the table
//
tInsertResult result;
result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
return result.second; // Insert a function using its unmangled name as the key.
} bool insertUnmangled(TFunction *function);
TSymbol* find(const TString& name) const TSymbol *find(const TString &name) const;
{
tLevel::const_iterator it = level.find(name);
if (it == level.end())
return 0;
else
return (*it).second;
}
static int nextUniqueId() static int nextUniqueId()
{ {
...@@ -348,12 +333,12 @@ public: ...@@ -348,12 +333,12 @@ public:
precisionStack.pop_back(); precisionStack.pop_back();
} }
bool declare(TSymbol &symbol) bool declare(TSymbol *symbol)
{ {
return insert(currentLevel(), symbol); return insert(currentLevel(), symbol);
} }
bool insert(ESymbolLevel level, TSymbol &symbol) bool insert(ESymbolLevel level, TSymbol *symbol)
{ {
return table[level]->insert(symbol); return table[level]->insert(symbol);
} }
...@@ -362,7 +347,7 @@ public: ...@@ -362,7 +347,7 @@ public:
{ {
TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConstExpr, 1)); TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConstExpr, 1));
constant->getConstPointer()->setIConst(value); constant->getConstPointer()->setIConst(value);
return insert(level, *constant); return insert(level, constant);
} }
void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0) void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
...@@ -448,7 +433,7 @@ public: ...@@ -448,7 +433,7 @@ public:
} }
ASSERT(hasUnmangledBuiltIn(name)); ASSERT(hasUnmangledBuiltIn(name));
insert(level, *function); insert(level, function);
} }
} }
......
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