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/Initialize.cpp b/src/OpenGL/compiler/Initialize.cpp
index 7e7667d..090faa8 100644
--- a/src/OpenGL/compiler/Initialize.cpp
+++ b/src/OpenGL/compiler/Initialize.cpp
@@ -427,10 +427,10 @@
fields->push_back(diff);
TStructure *depthRangeStruct = new TStructure(NewPoolTString("gl_DepthRangeParameters"), fields);
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));
depthRange->setQualifier(EvqUniform);
- symbolTable.insert(COMMON_BUILTINS, *depthRange);
+ symbolTable.insert(COMMON_BUILTINS, depthRange);
//
// Implementation dependent built-in constants.
@@ -460,18 +460,18 @@
switch(shaderType)
{
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_FrontFacing"), TType(EbtBool, EbpUndefined, EvqFrontFacing, 1)));
- 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_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
- symbolTable.insert(ESSL3_BUILTINS, *new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
+ 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_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_FragData[gl_MaxDrawBuffers]"), TType(EbtFloat, EbpMedium, EvqFragData, 4)));
+ symbolTable.insert(ESSL3_BUILTINS, new TVariable(NewPoolTString("gl_FragDepth"), TType(EbtFloat, EbpHigh, EvqFragDepth, 1)));
break;
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_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_VertexID"), TType(EbtInt, EbpHigh, EvqVertexID, 1)));
+ 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(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)));
break;
default: assert(false && "Language not supported");
}
@@ -484,7 +484,7 @@
// Set up gl_FragData. The array size.
TType fragData(EbtFloat, EbpMedium, EvqFragData, 4, 1, true);
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;
default: break;
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();
diff --git a/src/OpenGL/compiler/SymbolTable.cpp b/src/OpenGL/compiler/SymbolTable.cpp
index b2e48e8..22bf292 100644
--- a/src/OpenGL/compiler/SymbolTable.cpp
+++ b/src/OpenGL/compiler/SymbolTable.cpp
@@ -27,8 +27,8 @@
#include <limits.h>
#include <algorithm>
-#if defined(_MSC_VER) && MSC_VER < 1900
-#define snprintf _snprintf
+#if defined(_MSC_VER) && MSC_VER < 1900
+#define snprintf _snprintf
#endif
int TSymbolTableLevel::uniqueId = 0;
@@ -195,6 +195,35 @@
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
{
int level = currentLevel();
diff --git a/src/OpenGL/compiler/SymbolTable.h b/src/OpenGL/compiler/SymbolTable.h
index c4fdbfe..3bc7ff4 100644
--- a/src/OpenGL/compiler/SymbolTable.h
+++ b/src/OpenGL/compiler/SymbolTable.h
@@ -206,27 +206,12 @@
TSymbolTableLevel() { }
~TSymbolTableLevel();
- bool insert(TSymbol &symbol)
- {
- symbol.setUniqueId(nextUniqueId());
+ bool insert(TSymbol *symbol);
- //
- // returning true means symbol was added to the table
- //
- tInsertResult result;
- result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
+ // Insert a function using its unmangled name as the key.
+ bool insertUnmangled(TFunction *function);
- return result.second;
- }
-
- TSymbol* find(const TString& name) const
- {
- tLevel::const_iterator it = level.find(name);
- if (it == level.end())
- return 0;
- else
- return (*it).second;
- }
+ TSymbol *find(const TString &name) const;
static int nextUniqueId()
{
@@ -348,12 +333,12 @@
precisionStack.pop_back();
}
- bool declare(TSymbol &symbol)
+ bool declare(TSymbol *symbol)
{
return insert(currentLevel(), symbol);
}
- bool insert(ESymbolLevel level, TSymbol &symbol)
+ bool insert(ESymbolLevel level, TSymbol *symbol)
{
return table[level]->insert(symbol);
}
@@ -362,7 +347,7 @@
{
TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConstExpr, 1));
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)
@@ -448,7 +433,7 @@
}
ASSERT(hasUnmangledBuiltIn(name));
- insert(level, *function);
+ insert(level, function);
}
}