mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9329 from ethereum/optimiser-token
Disallow language keywords to be used as identifiers by NameDispenser and VarNameCleaner
This commit is contained in:
commit
cb2c9823c7
@ -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.
|
||||||
|
@ -152,6 +152,11 @@ static Token keywordByName(string const& _name)
|
|||||||
return it == keywords.end() ? Token::Identifier : it->second;
|
return it == keywords.end() ? Token::Identifier : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isYulKeyword(string const& _literal)
|
||||||
|
{
|
||||||
|
return _literal == "leave" || isYulKeyword(keywordByName(_literal));
|
||||||
|
}
|
||||||
|
|
||||||
tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(string const& _literal)
|
tuple<Token, unsigned int, unsigned int> fromIdentifierOrKeyword(string const& _literal)
|
||||||
{
|
{
|
||||||
auto positionM = find_if(_literal.begin(), _literal.end(), ::isdigit);
|
auto positionM = find_if(_literal.begin(), _literal.end(), ::isdigit);
|
||||||
|
@ -327,6 +327,8 @@ namespace TokenTraits
|
|||||||
tok == Token::TrueLiteral || tok == Token::FalseLiteral || tok == Token::HexStringLiteral || tok == Token::Hex;
|
tok == Token::TrueLiteral || tok == Token::FalseLiteral || tok == Token::HexStringLiteral || tok == Token::Hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isYulKeyword(std::string const& _literal);
|
||||||
|
|
||||||
inline Token AssignmentToBinaryOp(Token op)
|
inline Token AssignmentToBinaryOp(Token op)
|
||||||
{
|
{
|
||||||
solAssert(isAssignmentOp(op) && op != Token::Assign, "");
|
solAssert(isAssignmentOp(op) && op != Token::Assign, "");
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user