mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Prevent externally used functions from being removed.
This commit is contained in:
@@ -49,7 +49,7 @@ string ABIFunctions::tupleEncoder(
|
||||
if (_encodeAsLibraryTypes)
|
||||
functionName += "_library";
|
||||
|
||||
return createFunction(functionName, [&]() {
|
||||
return createExternallyUsedFunction(functionName, [&]() {
|
||||
solAssert(!_givenTypes.empty(), "");
|
||||
|
||||
// Note that the values are in reverse due to the difference in calling semantics.
|
||||
@@ -113,7 +113,7 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
|
||||
|
||||
solAssert(!_types.empty(), "");
|
||||
|
||||
return createFunction(functionName, [&]() {
|
||||
return createExternallyUsedFunction(functionName, [&]() {
|
||||
TypePointers decodingTypes;
|
||||
for (auto const& t: _types)
|
||||
decodingTypes.emplace_back(t->decodingType());
|
||||
@@ -176,13 +176,13 @@ string ABIFunctions::tupleDecoder(TypePointers const& _types, bool _fromMemory)
|
||||
});
|
||||
}
|
||||
|
||||
string ABIFunctions::requestedFunctions()
|
||||
pair<string, set<string>> ABIFunctions::requestedFunctions()
|
||||
{
|
||||
string result;
|
||||
for (auto const& f: m_requestedFunctions)
|
||||
result += f.second;
|
||||
m_requestedFunctions.clear();
|
||||
return result;
|
||||
return make_pair(result, std::move(m_externallyUsedFunctions));
|
||||
}
|
||||
|
||||
string ABIFunctions::cleanupFunction(Type const& _type, bool _revertOnFailure)
|
||||
@@ -1697,6 +1697,13 @@ string ABIFunctions::createFunction(string const& _name, function<string ()> con
|
||||
return _name;
|
||||
}
|
||||
|
||||
string ABIFunctions::createExternallyUsedFunction(string const& _name, function<string ()> const& _creator)
|
||||
{
|
||||
string name = createFunction(_name, _creator);
|
||||
m_externallyUsedFunctions.insert(name);
|
||||
return name;
|
||||
}
|
||||
|
||||
size_t ABIFunctions::headSize(TypePointers const& _targetTypes)
|
||||
{
|
||||
size_t headSize = 0;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
namespace dev {
|
||||
@@ -80,8 +81,11 @@ public:
|
||||
/// stack slot, it takes exactly that number of values.
|
||||
std::string tupleDecoder(TypePointers const& _types, bool _fromMemory = false);
|
||||
|
||||
/// @returns concatenation of all generated functions.
|
||||
std::string requestedFunctions();
|
||||
/// @returns concatenation of all generated functions and a set of the
|
||||
/// externally used functions.
|
||||
/// Clears the internal list, i.e. calling it again will result in an
|
||||
/// empty return value.
|
||||
std::pair<std::string, std::set<std::string>> requestedFunctions();
|
||||
|
||||
private:
|
||||
/// @returns the name of the cleanup function for the given type and
|
||||
@@ -224,12 +228,17 @@ private:
|
||||
/// cases.
|
||||
std::string createFunction(std::string const& _name, std::function<std::string()> const& _creator);
|
||||
|
||||
/// Helper function that uses @a _creator to create a function and add it to
|
||||
/// @a m_requestedFunctions if it has not been created yet and returns @a _name in both
|
||||
/// cases. Also adds it to the list of externally used functions.
|
||||
std::string createExternallyUsedFunction(std::string const& _name, std::function<std::string()> const& _creator);
|
||||
|
||||
/// @returns the size of the static part of the encoding of the given types.
|
||||
static size_t headSize(TypePointers const& _targetTypes);
|
||||
|
||||
/// Map from function name to code for a multi-use function.
|
||||
std::map<std::string, std::string> m_requestedFunctions;
|
||||
|
||||
std::set<std::string> m_externallyUsedFunctions;
|
||||
EVMVersion m_evmVersion;
|
||||
};
|
||||
|
||||
|
||||
@@ -313,6 +313,7 @@ void CompilerContext::resetVisitedNodes(ASTNode const* _node)
|
||||
void CompilerContext::appendInlineAssembly(
|
||||
string const& _assembly,
|
||||
vector<string> const& _localVariables,
|
||||
set<string> const&,
|
||||
bool _system
|
||||
)
|
||||
{
|
||||
|
||||
@@ -206,10 +206,12 @@ public:
|
||||
/// Appends inline assembly (strict mode).
|
||||
/// @a _replacements are string-matching replacements that are performed prior to parsing the inline assembly.
|
||||
/// @param _localVariables assigns stack positions to variables with the last one being the stack top
|
||||
/// @param _externallyUsedFunctions a set of function names that are not to be renamed or removed.
|
||||
/// @param _system if true, this is a "system-level" assembly where all functions use named labels.
|
||||
void appendInlineAssembly(
|
||||
std::string const& _assembly,
|
||||
std::vector<std::string> const& _localVariables = std::vector<std::string>(),
|
||||
std::set<std::string> const& _externallyUsedFunctions = std::set<std::string>(),
|
||||
bool _system = false
|
||||
);
|
||||
|
||||
|
||||
@@ -874,9 +874,9 @@ void ContractCompiler::appendMissingFunctions()
|
||||
solAssert(m_context.nextFunctionToCompile() != function, "Compiled the wrong function?");
|
||||
}
|
||||
m_context.appendMissingLowLevelFunctions();
|
||||
string abiFunctions = m_context.abiFunctions().requestedFunctions();
|
||||
if (!abiFunctions.empty())
|
||||
m_context.appendInlineAssembly("{" + move(abiFunctions) + "}", {}, true);
|
||||
auto abiFunctions = m_context.abiFunctions().requestedFunctions();
|
||||
if (!abiFunctions.first.empty())
|
||||
m_context.appendInlineAssembly("{" + move(abiFunctions.first) + "}", {}, abiFunctions.second, true);
|
||||
}
|
||||
|
||||
void ContractCompiler::appendModifierOrFunctionCode()
|
||||
|
||||
Reference in New Issue
Block a user