Commit d4ceab12 by Nicolas Capens Committed by Shannon Woods

Detect redefinition of functions and variables.

TRAC #21840 Signed-off-by: Jamie Madill Signed-off-by: Shannon Woods Author: Nicolas Capens
parent 5d1cffdc
......@@ -907,8 +907,9 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction*
{
// First find by unmangled name to check whether the function name has been
// hidden by a variable name or struct typename.
// If a function is found, check for one with a matching argument list.
const TSymbol* symbol = symbolTable.find(call->getName(), builtIn);
if (symbol == 0) {
if (symbol == 0 || symbol->isFunction()) {
symbol = symbolTable.find(call->getMangledName(), builtIn);
}
......
......@@ -190,17 +190,22 @@ public:
TSymbolTableLevel() { }
~TSymbolTableLevel();
bool insert(TSymbol& symbol)
bool insert(const TString &name, TSymbol &symbol)
{
//
// returning true means symbol was added to the table
//
tInsertResult result;
result = level.insert(tLevelPair(symbol.getMangledName(), &symbol));
result = level.insert(tLevelPair(name, &symbol));
return result.second;
}
bool insert(TSymbol &symbol)
{
return insert(symbol.getMangledName(), symbol);
}
TSymbol* find(const TString& name) const
{
tLevel::const_iterator it = level.find(name);
......
......@@ -1030,6 +1030,24 @@ function_prototype
}
//
// Check for previously declared variables using the same name.
//
TSymbol *prevSym = context->symbolTable.find($1->getName());
if (prevSym)
{
if (!prevSym->isFunction())
{
context->error(@2, "redefinition", $1->getName().c_str(), "function");
context->recover();
}
}
else
{
// Insert the unmangled name to detect potential future redefinition as a variable.
context->symbolTable.getOuterLevel()->insert($1->getName(), *$1);
}
//
// If this is a redeclaration, it could also be a definition,
// in which case, we want to use the variable names from this one, and not the one that's
// being redeclared. So, pass back up this declaration, not the one in the symbol table.
......
......@@ -2097,7 +2097,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
case EOB_ACT_END_OF_FILE:
{
if ( yywrap(yyscanner ) )
return 0;
return EOF;
if ( ! yyg->yy_did_buffer_switch_on_eof )
YY_NEW_FILE;
......
......@@ -720,20 +720,20 @@ static const yytype_uint16 yyrline[] =
756, 764, 775, 779, 780, 790, 800, 810, 823, 824,
834, 847, 851, 855, 859, 860, 873, 874, 887, 888,
901, 902, 919, 920, 933, 934, 935, 936, 937, 941,
944, 955, 963, 990, 995, 1009, 1046, 1049, 1056, 1064,
1085, 1106, 1116, 1144, 1149, 1159, 1164, 1174, 1177, 1180,
1183, 1189, 1196, 1199, 1221, 1239, 1263, 1286, 1290, 1308,
1316, 1348, 1368, 1389, 1398, 1421, 1424, 1430, 1438, 1446,
1454, 1464, 1471, 1474, 1477, 1483, 1486, 1501, 1505, 1509,
1513, 1517, 1522, 1527, 1532, 1537, 1542, 1547, 1552, 1557,
1562, 1567, 1572, 1577, 1581, 1585, 1593, 1601, 1605, 1618,
1618, 1632, 1632, 1641, 1644, 1660, 1693, 1697, 1703, 1710,
1725, 1729, 1733, 1734, 1740, 1741, 1742, 1743, 1744, 1748,
1749, 1749, 1749, 1759, 1760, 1764, 1764, 1765, 1765, 1770,
1773, 1783, 1786, 1792, 1793, 1797, 1805, 1809, 1819, 1824,
1841, 1841, 1846, 1846, 1853, 1853, 1861, 1864, 1870, 1873,
1879, 1883, 1890, 1897, 1904, 1911, 1922, 1931, 1935, 1942,
1945, 1951, 1951
944, 955, 963, 990, 995, 1009, 1064, 1067, 1074, 1082,
1103, 1124, 1134, 1162, 1167, 1177, 1182, 1192, 1195, 1198,
1201, 1207, 1214, 1217, 1239, 1257, 1281, 1304, 1308, 1326,
1334, 1366, 1386, 1407, 1416, 1439, 1442, 1448, 1456, 1464,
1472, 1482, 1489, 1492, 1495, 1501, 1504, 1519, 1523, 1527,
1531, 1535, 1540, 1545, 1550, 1555, 1560, 1565, 1570, 1575,
1580, 1585, 1590, 1595, 1599, 1603, 1611, 1619, 1623, 1636,
1636, 1650, 1650, 1659, 1662, 1678, 1711, 1715, 1721, 1728,
1743, 1747, 1751, 1752, 1758, 1759, 1760, 1761, 1762, 1766,
1767, 1767, 1767, 1777, 1778, 1782, 1782, 1783, 1783, 1788,
1791, 1801, 1804, 1810, 1811, 1815, 1823, 1827, 1837, 1842,
1859, 1859, 1864, 1864, 1871, 1871, 1879, 1882, 1888, 1891,
1897, 1901, 1908, 1915, 1922, 1929, 1940, 1949, 1953, 1960,
1963, 1969, 1969
};
#endif
......@@ -3285,6 +3285,24 @@ yyreduce:
}
//
// Check for previously declared variables using the same name.
//
TSymbol *prevSym = context->symbolTable.find((yyvsp[(1) - (2)].interm.function)->getName());
if (prevSym)
{
if (!prevSym->isFunction())
{
context->error((yylsp[(2) - (2)]), "redefinition", (yyvsp[(1) - (2)].interm.function)->getName().c_str(), "function");
context->recover();
}
}
else
{
// Insert the unmangled name to detect potential future redefinition as a variable.
context->symbolTable.getOuterLevel()->insert((yyvsp[(1) - (2)].interm.function)->getName(), *(yyvsp[(1) - (2)].interm.function));
}
//
// If this is a redeclaration, it could also be a definition,
// in which case, we want to use the variable names from this one, and not the one that's
// being redeclared. So, pass back up this declaration, not the one in the symbol table.
......
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