Disallow language keywords to be used as identifiers by NameDispenser and VarNameCleaner

Also introduce isRestrictedIdentifier helper in OptimizerUtilities
This commit is contained in:
Alex Beregszaszi 2020-07-06 18:25:12 +01:00
parent 2ebc4bb9a7
commit 2426616859
5 changed files with 21 additions and 6 deletions

View File

@ -22,6 +22,7 @@ Bugfixes:
* SMTChecker: Fix internal error on fixed bytes index access. * SMTChecker: Fix internal error on fixed bytes index access.
* References Resolver: Fix internal bug when using constructor for library. * References Resolver: Fix internal bug when using constructor for library.
* Yul Optimizer: Make function inlining order more resilient to whether or not unrelated source files are present. * Yul Optimizer: Make function inlining order more resilient to whether or not unrelated source files are present.
* Yul Optimizer: Ensure that Yul keywords are not mistakenly used by the NameDispenser and VarNameCleaners. The bug would manifest as uncompilable code.
* Type Checker: Disallow signed literals as exponent in exponentiation operator. * Type Checker: Disallow signed literals as exponent in exponentiation operator.
* Allow `type(Contract).name` for abstract contracts and interfaces. * Allow `type(Contract).name` for abstract contracts and interfaces.
* Type Checker: Disallow structs containing nested mapping in memory as parameters for library functions. * Type Checker: Disallow structs containing nested mapping in memory as parameters for library functions.

View File

@ -22,8 +22,10 @@
#include <libyul/optimiser/NameDispenser.h> #include <libyul/optimiser/NameDispenser.h>
#include <libyul/optimiser/NameCollector.h> #include <libyul/optimiser/NameCollector.h>
#include <libyul/optimiser/OptimizerUtilities.h>
#include <libyul/AsmData.h> #include <libyul/AsmData.h>
#include <libyul/Dialect.h> #include <libyul/Dialect.h>
#include <libyul/YulString.h>
#include <libsolutil/CommonData.h> #include <libsolutil/CommonData.h>
@ -57,7 +59,5 @@ YulString NameDispenser::newName(YulString _nameHint)
bool NameDispenser::illegalName(YulString _name) bool NameDispenser::illegalName(YulString _name)
{ {
if (_name.empty() || m_usedNames.count(_name) || m_dialect.builtin(_name)) return isRestrictedIdentifier(m_dialect, _name) || m_usedNames.count(_name);
return true;
return false;
} }

View File

@ -21,15 +21,19 @@
#include <libyul/optimiser/OptimizerUtilities.h> #include <libyul/optimiser/OptimizerUtilities.h>
#include <libyul/Dialect.h>
#include <libyul/AsmData.h> #include <libyul/AsmData.h>
#include <liblangutil/Token.h>
#include <libsolutil/CommonData.h> #include <libsolutil/CommonData.h>
#include <boost/range/algorithm_ext/erase.hpp> #include <boost/range/algorithm_ext/erase.hpp>
using namespace std; using namespace std;
using namespace solidity; using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::util; using namespace solidity::util;
using namespace solidity::yul;
void yul::removeEmptyBlocks(Block& _block) void yul::removeEmptyBlocks(Block& _block)
{ {
@ -38,3 +42,8 @@ void yul::removeEmptyBlocks(Block& _block)
}; };
boost::range::remove_erase_if(_block.statements, isEmptyBlock); boost::range::remove_erase_if(_block.statements, isEmptyBlock);
} }
bool yul::isRestrictedIdentifier(Dialect const& _dialect, YulString const& _identifier)
{
return _identifier.empty() || TokenTraits::isYulKeyword(_identifier.str()) || _dialect.builtin(_identifier);
}

View File

@ -23,6 +23,8 @@
#include <libsolutil/Common.h> #include <libsolutil/Common.h>
#include <libyul/AsmDataForward.h> #include <libyul/AsmDataForward.h>
#include <libyul/Dialect.h>
#include <libyul/YulString.h>
namespace solidity::yul namespace solidity::yul
{ {
@ -30,4 +32,8 @@ namespace solidity::yul
/// Removes statements that are just empty blocks (non-recursive). /// Removes statements that are just empty blocks (non-recursive).
void removeEmptyBlocks(Block& _block); void removeEmptyBlocks(Block& _block);
/// Returns true if a given literal can not be used as an identifier.
/// This includes Yul keywords and builtins of the given dialect.
bool isRestrictedIdentifier(Dialect const& _dialect, YulString const& _identifier);
} }

View File

@ -17,6 +17,7 @@
// SPDX-License-Identifier: GPL-3.0 // SPDX-License-Identifier: GPL-3.0
#include <libyul/optimiser/VarNameCleaner.h> #include <libyul/optimiser/VarNameCleaner.h>
#include <libyul/optimiser/OptimizerUtilities.h>
#include <libyul/AsmData.h> #include <libyul/AsmData.h>
#include <libyul/Dialect.h> #include <libyul/Dialect.h>
@ -110,9 +111,7 @@ YulString VarNameCleaner::findCleanName(YulString const& _name) const
bool VarNameCleaner::isUsedName(YulString const& _name) const bool VarNameCleaner::isUsedName(YulString const& _name) const
{ {
if (_name.empty() || m_dialect.builtin(_name) || m_usedNames.count(_name)) return isRestrictedIdentifier(m_dialect, _name) || m_usedNames.count(_name);
return true;
return false;
} }
YulString VarNameCleaner::stripSuffix(YulString const& _name) const YulString VarNameCleaner::stripSuffix(YulString const& _name) const