run addMissingFunctions only once

This commit is contained in:
Mathias Baumann 2020-05-05 16:53:30 +02:00
parent 3212cb6caa
commit eb4926cb48
6 changed files with 41 additions and 2 deletions

View File

@ -11,6 +11,7 @@ Compiler Features:
Bugfixes:
* ABI: Skip ``private`` or ``internal`` constructors.
* Type Checker: Disallow accessing ``runtimeCode`` for contract types that contain immutable state variables.
* Fixed an "Assembly Exception in Bytecode" error where requested functions were generated twice.

View File

@ -49,6 +49,9 @@ void Compiler::compileContract(
m_runtimeSub = creationCompiler.compileConstructor(_contract, _otherCompilers);
m_context.optimise(m_optimiserSettings);
solAssert(m_context.requestedYulFunctionsRan(), "requestedYulFunctions() was not called.");
solAssert(m_runtimeContext.requestedYulFunctionsRan(), "requestedYulFunctions() was not called.");
}
std::shared_ptr<evmasm::Assembly> Compiler::runtimeAssemblyPtr() const

View File

@ -192,6 +192,9 @@ void CompilerContext::appendMissingLowLevelFunctions()
pair<string, set<string>> CompilerContext::requestedYulFunctions()
{
solAssert(!m_requestedYulFunctionsRan, "requestedYulFunctions called more than once.");
m_requestedYulFunctionsRan = true;
set<string> empty;
swap(empty, m_externallyUsedYulFunctions);
return {m_yulFunctionCollector.requestedFunctions(), std::move(empty)};

View File

@ -167,6 +167,7 @@ public:
/// Clears the internal list, i.e. calling it again will result in an
/// empty return value.
std::pair<std::string, std::set<std::string>> requestedYulFunctions();
bool requestedYulFunctionsRan() const { return m_requestedYulFunctionsRan; }
/// Returns the distance of the given local variable from the bottom of the stack (of the current function).
unsigned baseStackOffsetOfVariable(Declaration const& _declaration) const;
@ -389,6 +390,8 @@ private:
YulUtilFunctions m_yulUtilFunctions;
/// The queue of low-level functions to generate.
std::queue<std::tuple<std::string, unsigned, unsigned, std::function<void(CompilerContext&)>>> m_lowLevelFunctionGenerationQueue;
/// Flag to check that requestedYulFunctions() was called exactly once
bool m_requestedYulFunctionsRan = false;
};
}

View File

@ -103,8 +103,6 @@ void ContractCompiler::compileContract(
// and adds the function to the compilation queue. Additionally internal functions,
// which are referenced directly or indirectly will be added.
appendFunctionSelector(_contract);
// This processes the above populated queue until it is empty.
appendMissingFunctions();
}
size_t ContractCompiler::compileConstructor(
@ -215,6 +213,9 @@ size_t ContractCompiler::deployLibrary(ContractDefinition const& _contract)
solAssert(!!m_runtimeCompiler, "");
solAssert(_contract.isLibrary(), "Tried to deploy contract as library.");
appendMissingFunctions();
m_runtimeCompiler->appendMissingFunctions();
CompilerContext::LocationSetter locationSetter(m_context, _contract);
solAssert(m_context.runtimeSub() != size_t(-1), "Runtime sub not registered");

View File

@ -0,0 +1,28 @@
pragma solidity ^0.6.0;
pragma experimental ABIEncoderV2;
contract Ownable {
address private _owner;
modifier onlyOwner() {
require(msg.sender == _owner, "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public onlyOwner { }
}
library VoteTiming {
function init(uint phaseLength) internal pure {
require(true, "");
}
}
contract Voting is Ownable {
constructor() public {
VoteTiming.init(1);
}
}
// ----
// Warning: (324-340): Unused function parameter. Remove or comment out the variable name to silence this warning.