diff options
author | chriseth <chris@ethereum.org> | 2018-01-17 19:05:43 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2018-10-17 20:12:10 +0800 |
commit | 5e01d767d02d064a064a67dcf95ee299c46f741f (patch) | |
tree | 055a2533fa92111b85203eff0f1f1e8c63e38492 /libsolidity | |
parent | ba1588828f45b242bc09899e4f307f7fda9c5ab6 (diff) | |
download | dexon-solidity-5e01d767d02d064a064a67dcf95ee299c46f741f.tar.gz dexon-solidity-5e01d767d02d064a064a67dcf95ee299c46f741f.tar.zst dexon-solidity-5e01d767d02d064a064a67dcf95ee299c46f741f.zip |
Prevent externally used functions from being removed.
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/codegen/ABIFunctions.cpp | 15 | ||||
-rw-r--r-- | libsolidity/codegen/ABIFunctions.h | 15 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerContext.cpp | 1 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerContext.h | 2 | ||||
-rw-r--r-- | libsolidity/codegen/ContractCompiler.cpp | 6 |
5 files changed, 29 insertions, 10 deletions
diff --git a/libsolidity/codegen/ABIFunctions.cpp b/libsolidity/codegen/ABIFunctions.cpp index 6c27533c..bd29b382 100644 --- a/libsolidity/codegen/ABIFunctions.cpp +++ b/libsolidity/codegen/ABIFunctions.cpp @@ -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; diff --git a/libsolidity/codegen/ABIFunctions.h b/libsolidity/codegen/ABIFunctions.h index 3caaa1d9..e9ffe4fb 100644 --- a/libsolidity/codegen/ABIFunctions.h +++ b/libsolidity/codegen/ABIFunctions.h @@ -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; }; diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 089386b5..210b613d 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -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 ) { diff --git a/libsolidity/codegen/CompilerContext.h b/libsolidity/codegen/CompilerContext.h index 3f357821..5bdc1d19 100644 --- a/libsolidity/codegen/CompilerContext.h +++ b/libsolidity/codegen/CompilerContext.h @@ -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 ); diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index c845da8f..1fdf3483 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -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() |