mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #14513 from junaire/yul-backend-namespace-std
Purge using namespace std from libyul/backends
This commit is contained in:
		
						commit
						925bfeb24b
					
				| @ -28,7 +28,6 @@ | ||||
| 
 | ||||
| #include <libsolutil/StackTooDeepString.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| using namespace solidity::util; | ||||
|  | ||||
| @ -30,7 +30,6 @@ | ||||
| 
 | ||||
| #include <variant> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| using namespace solidity::util; | ||||
| @ -48,9 +47,9 @@ struct MiniEVMInterpreter | ||||
| 		return std::visit(*this, _expr); | ||||
| 	} | ||||
| 
 | ||||
| 	u256 eval(evmasm::Instruction _instr, vector<Expression> const& _arguments) | ||||
| 	u256 eval(evmasm::Instruction _instr, std::vector<Expression> const& _arguments) | ||||
| 	{ | ||||
| 		vector<u256> args; | ||||
| 		std::vector<u256> args; | ||||
| 		for (auto const& arg: _arguments) | ||||
| 			args.emplace_back(eval(arg)); | ||||
| 		switch (_instr) | ||||
| @ -92,7 +91,7 @@ struct MiniEVMInterpreter | ||||
| 
 | ||||
| void ConstantOptimiser::visit(Expression& _e) | ||||
| { | ||||
| 	if (holds_alternative<Literal>(_e)) | ||||
| 	if (std::holds_alternative<Literal>(_e)) | ||||
| 	{ | ||||
| 		Literal const& literal = std::get<Literal>(_e); | ||||
| 		if (literal.kind != LiteralKind::Number) | ||||
| @ -115,7 +114,7 @@ Expression const* RepresentationFinder::tryFindRepresentation(u256 const& _value | ||||
| 		return nullptr; | ||||
| 
 | ||||
| 	Representation const& repr = findRepresentation(_value); | ||||
| 	if (holds_alternative<Literal>(*repr.expression)) | ||||
| 	if (std::holds_alternative<Literal>(*repr.expression)) | ||||
| 		return nullptr; | ||||
| 	else | ||||
| 		return repr.expression.get(); | ||||
| @ -180,7 +179,7 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu | ||||
| Representation RepresentationFinder::represent(u256 const& _value) const | ||||
| { | ||||
| 	Representation repr; | ||||
| 	repr.expression = make_unique<Expression>(Literal{m_debugData, LiteralKind::Number, YulString{formatNumber(_value)}, {}}); | ||||
| 	repr.expression = std::make_unique<Expression>(Literal{m_debugData, LiteralKind::Number, YulString{formatNumber(_value)}, {}}); | ||||
| 	repr.cost = m_meter.costs(*repr.expression); | ||||
| 	return repr; | ||||
| } | ||||
| @ -191,7 +190,7 @@ Representation RepresentationFinder::represent( | ||||
| ) const | ||||
| { | ||||
| 	Representation repr; | ||||
| 	repr.expression = make_unique<Expression>(FunctionCall{ | ||||
| 	repr.expression = std::make_unique<Expression>(FunctionCall{ | ||||
| 		m_debugData, | ||||
| 		Identifier{m_debugData, _instruction}, | ||||
| 		{ASTCopier{}.translate(*_argument.expression)} | ||||
| @ -207,7 +206,7 @@ Representation RepresentationFinder::represent( | ||||
| ) const | ||||
| { | ||||
| 	Representation repr; | ||||
| 	repr.expression = make_unique<Expression>(FunctionCall{ | ||||
| 	repr.expression = std::make_unique<Expression>(FunctionCall{ | ||||
| 		m_debugData, | ||||
| 		Identifier{m_debugData, _instruction}, | ||||
| 		{ASTCopier{}.translate(*_arg1.expression), ASTCopier{}.translate(*_arg2.expression)} | ||||
|  | ||||
| @ -45,7 +45,6 @@ | ||||
| 
 | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| using namespace std; | ||||
| 
 | ||||
| namespace | ||||
| { | ||||
| @ -82,15 +81,15 @@ void cleanUnreachable(CFG& _cfg) | ||||
| /// Sets the ``recursive`` member to ``true`` for all recursive function calls.
 | ||||
| void markRecursiveCalls(CFG& _cfg) | ||||
| { | ||||
| 	map<CFG::BasicBlock*, vector<CFG::FunctionCall*>> callsPerBlock; | ||||
| 	std::map<CFG::BasicBlock*, std::vector<CFG::FunctionCall*>> callsPerBlock; | ||||
| 	auto const& findCalls = [&](CFG::BasicBlock* _block) | ||||
| 	{ | ||||
| 		if (auto* calls = util::valueOrNullptr(callsPerBlock, _block)) | ||||
| 			return *calls; | ||||
| 		vector<CFG::FunctionCall*>& calls = callsPerBlock[_block]; | ||||
| 		std::vector<CFG::FunctionCall*>& calls = callsPerBlock[_block]; | ||||
| 		util::BreadthFirstSearch<CFG::BasicBlock*>{{_block}}.run([&](CFG::BasicBlock* _block, auto _addChild) { | ||||
| 			for (auto& operation: _block->operations) | ||||
| 				if (auto* functionCall = get_if<CFG::FunctionCall>(&operation.operation)) | ||||
| 				if (auto* functionCall = std::get_if<CFG::FunctionCall>(&operation.operation)) | ||||
| 					calls.emplace_back(functionCall); | ||||
| 			std::visit(util::GenericVisitor{ | ||||
| 				[&](CFG::BasicBlock::MainExit const&) {}, | ||||
| @ -131,7 +130,7 @@ void markRecursiveCalls(CFG& _cfg) | ||||
| /// Entering such a block means that control flow will never return to a previously visited block.
 | ||||
| void markStartsOfSubGraphs(CFG& _cfg) | ||||
| { | ||||
| 	vector<CFG::BasicBlock*> entries; | ||||
| 	std::vector<CFG::BasicBlock*> entries; | ||||
| 	entries.emplace_back(_cfg.entry); | ||||
| 	for (auto&& functionInfo: _cfg.functionInfo | ranges::views::values) | ||||
| 		entries.emplace_back(functionInfo.entry); | ||||
| @ -141,17 +140,17 @@ void markStartsOfSubGraphs(CFG& _cfg) | ||||
| 		 * Detect bridges following Algorithm 1 in https://arxiv.org/pdf/2108.07346.pdf
 | ||||
| 		 * and mark the bridge targets as starts of sub-graphs. | ||||
| 		 */ | ||||
| 		set<CFG::BasicBlock*> visited; | ||||
| 		map<CFG::BasicBlock*, size_t> disc; | ||||
| 		map<CFG::BasicBlock*, size_t> low; | ||||
| 		map<CFG::BasicBlock*, CFG::BasicBlock*> parent; | ||||
| 		std::set<CFG::BasicBlock*> visited; | ||||
| 		std::map<CFG::BasicBlock*, size_t> disc; | ||||
| 		std::map<CFG::BasicBlock*, size_t> low; | ||||
| 		std::map<CFG::BasicBlock*, CFG::BasicBlock*> parent; | ||||
| 		size_t time = 0; | ||||
| 		auto dfs = [&](CFG::BasicBlock* _u, auto _recurse) -> void { | ||||
| 			visited.insert(_u); | ||||
| 			disc[_u] = low[_u] = time; | ||||
| 			time++; | ||||
| 
 | ||||
| 			vector<CFG::BasicBlock*> children = _u->entries; | ||||
| 			std::vector<CFG::BasicBlock*> children = _u->entries; | ||||
| 			visit(util::GenericVisitor{ | ||||
| 				[&](CFG::BasicBlock::Jump const& _jump) { | ||||
| 					children.emplace_back(_jump.target); | ||||
| @ -171,7 +170,7 @@ void markStartsOfSubGraphs(CFG& _cfg) | ||||
| 				{ | ||||
| 					parent[v] = _u; | ||||
| 					_recurse(v, _recurse); | ||||
| 					low[_u] = min(low[_u], low[v]); | ||||
| 					low[_u] = std::min(low[_u], low[v]); | ||||
| 					if (low[v] > disc[_u]) | ||||
| 					{ | ||||
| 						// _u <-> v is a cut edge in the undirected graph
 | ||||
| @ -186,7 +185,7 @@ void markStartsOfSubGraphs(CFG& _cfg) | ||||
| 					} | ||||
| 				} | ||||
| 				else if (v != parent[_u]) | ||||
| 					low[_u] = min(low[_u], disc[v]); | ||||
| 					low[_u] = std::min(low[_u], disc[v]); | ||||
| 		}; | ||||
| 		dfs(entry, dfs); | ||||
| 	} | ||||
| @ -234,7 +233,7 @@ std::unique_ptr<CFG> ControlFlowGraphBuilder::build( | ||||
| ControlFlowGraphBuilder::ControlFlowGraphBuilder( | ||||
| 	CFG& _graph, | ||||
| 	AsmAnalysisInfo const& _analysisInfo, | ||||
| 	map<FunctionDefinition const*, ControlFlowSideEffects> const& _functionSideEffects, | ||||
| 	std::map<FunctionDefinition const*, ControlFlowSideEffects> const& _functionSideEffects, | ||||
| 	Dialect const& _dialect | ||||
| ): | ||||
| 	m_graph(_graph), | ||||
| @ -271,7 +270,7 @@ void ControlFlowGraphBuilder::operator()(VariableDeclaration const& _varDecl) | ||||
| 	yulAssert(m_currentBlock, ""); | ||||
| 	auto declaredVariables = _varDecl.variables | ranges::views::transform([&](TypedName const& _var) { | ||||
| 		return VariableSlot{lookupVariable(_var.name), _var.debugData}; | ||||
| 	}) | ranges::to<vector<VariableSlot>>; | ||||
| 	}) | ranges::to<std::vector<VariableSlot>>; | ||||
| 	Stack input; | ||||
| 	if (_varDecl.value) | ||||
| 		input = visitAssignmentRightHandSide(*_varDecl.value, declaredVariables.size()); | ||||
| @ -287,7 +286,7 @@ void ControlFlowGraphBuilder::operator()(Assignment const& _assignment) | ||||
| { | ||||
| 	auto assignedVariables = _assignment.variableNames | ranges::views::transform([&](Identifier const& _var) { | ||||
| 		return VariableSlot{lookupVariable(_var.name), _var.debugData}; | ||||
| 	}) | ranges::to<vector<VariableSlot>>; | ||||
| 	}) | ranges::to<std::vector<VariableSlot>>; | ||||
| 
 | ||||
| 	Stack input = visitAssignmentRightHandSide(*_assignment.value, assignedVariables.size()); | ||||
| 	yulAssert(m_currentBlock); | ||||
| @ -314,7 +313,7 @@ void ControlFlowGraphBuilder::operator()(Block const& _block) | ||||
| { | ||||
| 	ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get()); | ||||
| 	for (auto const& statement: _block.statements) | ||||
| 		if (auto const* function = get_if<FunctionDefinition>(&statement)) | ||||
| 		if (auto const* function = std::get_if<FunctionDefinition>(&statement)) | ||||
| 			registerFunction(*function); | ||||
| 	for (auto const& statement: _block.statements) | ||||
| 		std::visit(*this, statement); | ||||
| @ -334,10 +333,10 @@ void ControlFlowGraphBuilder::operator()(If const& _if) | ||||
| void ControlFlowGraphBuilder::operator()(Switch const& _switch) | ||||
| { | ||||
| 	yulAssert(m_currentBlock, ""); | ||||
| 	shared_ptr<DebugData const> preSwitchDebugData = debugDataOf(_switch); | ||||
| 	std::shared_ptr<DebugData const> preSwitchDebugData = debugDataOf(_switch); | ||||
| 
 | ||||
| 	auto ghostVariableId = m_graph.ghostVariables.size(); | ||||
| 	YulString ghostVariableName("GHOST[" + to_string(ghostVariableId) + "]"); | ||||
| 	YulString ghostVariableName("GHOST[" + std::to_string(ghostVariableId) + "]"); | ||||
| 	auto& ghostVar = m_graph.ghostVariables.emplace_back(Scope::Variable{""_yulstring, ghostVariableName}); | ||||
| 
 | ||||
| 	// Artificially generate:
 | ||||
| @ -394,12 +393,12 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch) | ||||
| 
 | ||||
| void ControlFlowGraphBuilder::operator()(ForLoop const& _loop) | ||||
| { | ||||
| 	shared_ptr<DebugData const> preLoopDebugData = debugDataOf(_loop); | ||||
| 	std::shared_ptr<DebugData const> preLoopDebugData = debugDataOf(_loop); | ||||
| 	ScopedSaveAndRestore scopeRestore(m_scope, m_info.scopes.at(&_loop.pre).get()); | ||||
| 	(*this)(_loop.pre); | ||||
| 
 | ||||
| 	std::optional<bool> constantCondition; | ||||
| 	if (auto const* literalCondition = get_if<yul::Literal>(_loop.condition.get())) | ||||
| 	if (auto const* literalCondition = std::get_if<yul::Literal>(_loop.condition.get())) | ||||
| 		constantCondition = valueOfLiteral(*literalCondition) != 0; | ||||
| 
 | ||||
| 	CFG::BasicBlock& loopCondition = m_graph.makeBlock(debugDataOf(*_loop.condition)); | ||||
| @ -497,13 +496,13 @@ void ControlFlowGraphBuilder::registerFunction(FunctionDefinition const& _functi | ||||
| 				std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_param.name)), | ||||
| 				_param.debugData | ||||
| 			}; | ||||
| 		}) | ranges::to<vector>, | ||||
| 		}) | ranges::to<std::vector>, | ||||
| 		_functionDefinition.returnVariables | ranges::views::transform([&](auto const& _retVar) { | ||||
| 			return VariableSlot{ | ||||
| 				std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_retVar.name)), | ||||
| 				_retVar.debugData | ||||
| 			}; | ||||
| 		}) | ranges::to<vector>, | ||||
| 		}) | ranges::to<std::vector>, | ||||
| 		{}, | ||||
| 		m_functionSideEffects.at(&_functionDefinition).canContinue | ||||
| 	})).second; | ||||
| @ -609,7 +608,7 @@ Scope::Variable const& ControlFlowGraphBuilder::lookupVariable(YulString _name) | ||||
| } | ||||
| 
 | ||||
| void ControlFlowGraphBuilder::makeConditionalJump( | ||||
| 	shared_ptr<DebugData const> _debugData, | ||||
| 	std::shared_ptr<DebugData const> _debugData, | ||||
| 	StackSlot _condition, | ||||
| 	CFG::BasicBlock& _nonZero, | ||||
| 	CFG::BasicBlock& _zero | ||||
| @ -628,7 +627,7 @@ void ControlFlowGraphBuilder::makeConditionalJump( | ||||
| } | ||||
| 
 | ||||
| void ControlFlowGraphBuilder::jump( | ||||
| 	shared_ptr<DebugData const> _debugData, | ||||
| 	std::shared_ptr<DebugData const> _debugData, | ||||
| 	CFG::BasicBlock& _target, | ||||
| 	bool backwards | ||||
| ) | ||||
|  | ||||
| @ -42,7 +42,6 @@ | ||||
| #include <utility> | ||||
| #include <variant> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| using namespace solidity::util; | ||||
| @ -56,9 +55,9 @@ CodeTransform::CodeTransform( | ||||
| 	BuiltinContext& _builtinContext, | ||||
| 	ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen, | ||||
| 	UseNamedLabels _useNamedLabelsForFunctions, | ||||
| 	shared_ptr<Context> _context, | ||||
| 	vector<TypedName> _delayedReturnVariables, | ||||
| 	optional<AbstractAssembly::LabelID> _functionExitLabel | ||||
| 	std::shared_ptr<Context> _context, | ||||
| 	std::vector<TypedName> _delayedReturnVariables, | ||||
| 	std::optional<AbstractAssembly::LabelID> _functionExitLabel | ||||
| ): | ||||
| 	m_assembly(_assembly), | ||||
| 	m_info(_analysisInfo), | ||||
| @ -74,7 +73,7 @@ CodeTransform::CodeTransform( | ||||
| 	if (!m_context) | ||||
| 	{ | ||||
| 		// initialize
 | ||||
| 		m_context = make_shared<Context>(); | ||||
| 		m_context = std::make_shared<Context>(); | ||||
| 		if (m_allowStackOpt) | ||||
| 			m_context->variableReferences = VariableReferenceCounter::run(m_info, _block); | ||||
| 	} | ||||
| @ -103,7 +102,7 @@ void CodeTransform::freeUnusedVariables(bool _popUnusedSlotsAtStackTop) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (auto const& identifier: m_scope->identifiers) | ||||
| 		if (Scope::Variable const* var = get_if<Scope::Variable>(&identifier.second)) | ||||
| 		if (Scope::Variable const* var = std::get_if<Scope::Variable>(&identifier.second)) | ||||
| 			if (m_variablesScheduledForDeletion.count(var)) | ||||
| 				deleteVariable(*var); | ||||
| 	// Directly in a function body block, we can also delete the function arguments,
 | ||||
| @ -112,7 +111,7 @@ void CodeTransform::freeUnusedVariables(bool _popUnusedSlotsAtStackTop) | ||||
| 	// effect, so we only do it before that.
 | ||||
| 	if (!returnVariablesAndFunctionExitAreSetup() && !m_scope->functionScope && m_scope->superScope && m_scope->superScope->functionScope) | ||||
| 		for (auto const& identifier: m_scope->superScope->identifiers) | ||||
| 			if (Scope::Variable const* var = get_if<Scope::Variable>(&identifier.second)) | ||||
| 			if (Scope::Variable const* var = std::get_if<Scope::Variable>(&identifier.second)) | ||||
| 				if (m_variablesScheduledForDeletion.count(var)) | ||||
| 					deleteVariable(*var); | ||||
| 
 | ||||
| @ -317,7 +316,7 @@ void CodeTransform::operator()(Switch const& _switch) | ||||
| { | ||||
| 	visitExpression(*_switch.expression); | ||||
| 	int expressionHeight = m_assembly.stackHeight(); | ||||
| 	map<Case const*, AbstractAssembly::LabelID> caseBodies; | ||||
| 	std::map<Case const*, AbstractAssembly::LabelID> caseBodies; | ||||
| 	AbstractAssembly::LabelID end = m_assembly.newLabelId(); | ||||
| 	for (Case const& c: _switch.cases) | ||||
| 	{ | ||||
| @ -447,7 +446,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function) | ||||
| 
 | ||||
| 		// This vector holds the desired target positions of all stack slots and is
 | ||||
| 		// modified parallel to the actual stack.
 | ||||
| 		vector<int> stackLayout(static_cast<size_t>(m_assembly.stackHeight()), -1); | ||||
| 		std::vector<int> stackLayout(static_cast<size_t>(m_assembly.stackHeight()), -1); | ||||
| 		stackLayout[0] = static_cast<int>(_function.returnVariables.size()); // Move return label to the top
 | ||||
| 		for (auto&& [n, returnVariable]: ranges::views::enumerate(_function.returnVariables)) | ||||
| 			stackLayout.at(m_context->variableStackHeights.at( | ||||
| @ -463,7 +462,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function) | ||||
| 				"The function " + | ||||
| 				_function.name.str() + | ||||
| 				" has " + | ||||
| 				to_string(stackLayout.size() - 17) + | ||||
| 				std::to_string(stackLayout.size() - 17) + | ||||
| 				" parameters or return variables too many to fit the stack size." | ||||
| 			); | ||||
| 			stackError(std::move(error), m_assembly.stackHeight() - static_cast<int>(_function.parameters.size())); | ||||
| @ -479,7 +478,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function) | ||||
| 				else | ||||
| 				{ | ||||
| 					m_assembly.appendInstruction(evmasm::swapInstruction(static_cast<unsigned>(stackLayout.size()) - static_cast<unsigned>(stackLayout.back()) - 1u)); | ||||
| 					swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back()); | ||||
| 					std::swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back()); | ||||
| 				} | ||||
| 			for (size_t i = 0; i < stackLayout.size(); ++i) | ||||
| 				yulAssert(i == static_cast<size_t>(stackLayout[i]), "Error reshuffling stack."); | ||||
| @ -571,7 +570,7 @@ void CodeTransform::operator()(Block const& _block) | ||||
| 	m_scope = m_info.scopes.at(&_block).get(); | ||||
| 
 | ||||
| 	for (auto const& statement: _block.statements) | ||||
| 		if (auto function = get_if<FunctionDefinition>(&statement)) | ||||
| 		if (auto function = std::get_if<FunctionDefinition>(&statement)) | ||||
| 			createFunctionEntryID(*function); | ||||
| 
 | ||||
| 	int blockStartStackHeight = m_assembly.stackHeight(); | ||||
| @ -579,7 +578,7 @@ void CodeTransform::operator()(Block const& _block) | ||||
| 
 | ||||
| 	bool isOutermostFunctionBodyBlock = m_scope && m_scope->superScope && m_scope->superScope->functionScope; | ||||
| 	bool performValidation = !m_allowStackOpt || !isOutermostFunctionBodyBlock; | ||||
| 	finalizeBlock(_block, performValidation ? make_optional(blockStartStackHeight) : nullopt); | ||||
| 	finalizeBlock(_block, performValidation ? std::make_optional(blockStartStackHeight) : std::nullopt); | ||||
| 	m_scope = originalScope; | ||||
| } | ||||
| 
 | ||||
| @ -588,7 +587,7 @@ void CodeTransform::createFunctionEntryID(FunctionDefinition const& _function) | ||||
| 	Scope::Function& scopeFunction = std::get<Scope::Function>(m_scope->identifiers.at(_function.name)); | ||||
| 	yulAssert(!m_context->functionEntryIDs.count(&scopeFunction), ""); | ||||
| 
 | ||||
| 	optional<size_t> astID; | ||||
| 	std::optional<size_t> astID; | ||||
| 	if (_function.debugData) | ||||
| 		astID = _function.debugData->astID; | ||||
| 
 | ||||
| @ -659,16 +658,16 @@ void CodeTransform::setupReturnVariablesAndFunctionExit() | ||||
| namespace | ||||
| { | ||||
| 
 | ||||
| bool statementNeedsReturnVariableSetup(Statement const& _statement, vector<TypedName> const& _returnVariables) | ||||
| bool statementNeedsReturnVariableSetup(Statement const& _statement, std::vector<TypedName> const& _returnVariables) | ||||
| { | ||||
| 	if (holds_alternative<FunctionDefinition>(_statement)) | ||||
| 	if (std::holds_alternative<FunctionDefinition>(_statement)) | ||||
| 		return true; | ||||
| 	if ( | ||||
| 		holds_alternative<ExpressionStatement>(_statement) || | ||||
| 		holds_alternative<Assignment>(_statement) | ||||
| 		std::holds_alternative<ExpressionStatement>(_statement) || | ||||
| 		std::holds_alternative<Assignment>(_statement) | ||||
| 	) | ||||
| 	{ | ||||
| 		map<YulString, size_t> references = VariableReferencesCounter::countReferences(_statement); | ||||
| 		std::map<YulString, size_t> references = VariableReferencesCounter::countReferences(_statement); | ||||
| 		auto isReferenced = [&references](TypedName const& _returnVariable) { | ||||
| 			return references.count(_returnVariable.name); | ||||
| 		}; | ||||
| @ -680,7 +679,7 @@ bool statementNeedsReturnVariableSetup(Statement const& _statement, vector<Typed | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| void CodeTransform::visitStatements(vector<Statement> const& _statements) | ||||
| void CodeTransform::visitStatements(std::vector<Statement> const& _statements) | ||||
| { | ||||
| 	std::optional<AbstractAssembly::LabelID> jumpTarget = std::nullopt; | ||||
| 
 | ||||
| @ -716,7 +715,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements) | ||||
| 	freeUnusedVariables(); | ||||
| } | ||||
| 
 | ||||
| void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartStackHeight) | ||||
| void CodeTransform::finalizeBlock(Block const& _block, std::optional<int> blockStartStackHeight) | ||||
| { | ||||
| 	m_assembly.setSourceLocation(originLocationOf(_block)); | ||||
| 
 | ||||
| @ -725,7 +724,7 @@ void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartS | ||||
| 	// pop variables
 | ||||
| 	yulAssert(m_info.scopes.at(&_block).get() == m_scope, ""); | ||||
| 	for (auto const& id: m_scope->identifiers) | ||||
| 		if (holds_alternative<Scope::Variable>(id.second)) | ||||
| 		if (std::holds_alternative<Scope::Variable>(id.second)) | ||||
| 		{ | ||||
| 			Scope::Variable const& var = std::get<Scope::Variable>(id.second); | ||||
| 			if (m_allowStackOpt) | ||||
| @ -740,11 +739,11 @@ void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartS | ||||
| 	if (blockStartStackHeight) | ||||
| 	{ | ||||
| 		int deposit = m_assembly.stackHeight() - *blockStartStackHeight; | ||||
| 		yulAssert(deposit == 0, "Invalid stack height at end of block: " + to_string(deposit)); | ||||
| 		yulAssert(deposit == 0, "Invalid stack height at end of block: " + std::to_string(deposit)); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void CodeTransform::generateMultiAssignment(vector<Identifier> const& _variableNames) | ||||
| void CodeTransform::generateMultiAssignment(std::vector<Identifier> const& _variableNames) | ||||
| { | ||||
| 	yulAssert(m_scope, ""); | ||||
| 	for (auto const& variableName: _variableNames | ranges::views::reverse) | ||||
| @ -786,7 +785,7 @@ size_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulString | ||||
| 			"Variable " + | ||||
| 			_varName.str() + | ||||
| 			" is " + | ||||
| 			to_string(heightDiff - limit) + | ||||
| 			std::to_string(heightDiff - limit) + | ||||
| 			" slot(s) too deep inside the stack. " + | ||||
| 			stackTooDeepString | ||||
| 		); | ||||
| @ -798,7 +797,7 @@ size_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulString | ||||
| 
 | ||||
| int CodeTransform::variableStackHeight(YulString _name) const | ||||
| { | ||||
| 	Scope::Variable const* var = get_if<Scope::Variable>(m_scope->lookup(_name)); | ||||
| 	Scope::Variable const* var = std::get_if<Scope::Variable>(m_scope->lookup(_name)); | ||||
| 	yulAssert(var, ""); | ||||
| 	return static_cast<int>(m_context->variableStackHeights.at(var)); | ||||
| } | ||||
|  | ||||
| @ -38,7 +38,7 @@ | ||||
| 
 | ||||
| #include <regex> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace std::string_literals; | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| using namespace solidity::util; | ||||
| @ -46,9 +46,9 @@ using namespace solidity::util; | ||||
| namespace | ||||
| { | ||||
| 
 | ||||
| pair<YulString, BuiltinFunctionForEVM> createEVMFunction( | ||||
| std::pair<YulString, BuiltinFunctionForEVM> createEVMFunction( | ||||
| 	langutil::EVMVersion _evmVersion, | ||||
| 	string const& _name, | ||||
| 	std::string const& _name, | ||||
| 	evmasm::Instruction _instruction | ||||
| ) | ||||
| { | ||||
| @ -87,12 +87,12 @@ pair<YulString, BuiltinFunctionForEVM> createEVMFunction( | ||||
| 	return {name, std::move(f)}; | ||||
| } | ||||
| 
 | ||||
| pair<YulString, BuiltinFunctionForEVM> createFunction( | ||||
| 	string _name, | ||||
| std::pair<YulString, BuiltinFunctionForEVM> createFunction( | ||||
| 	std::string _name, | ||||
| 	size_t _params, | ||||
| 	size_t _returns, | ||||
| 	SideEffects _sideEffects, | ||||
| 	vector<optional<LiteralKind>> _literalArguments, | ||||
| 	std::vector<std::optional<LiteralKind>> _literalArguments, | ||||
| 	std::function<void(FunctionCall const&, AbstractAssembly&, BuiltinContext&)> _generateCode | ||||
| ) | ||||
| { | ||||
| @ -111,7 +111,7 @@ pair<YulString, BuiltinFunctionForEVM> createFunction( | ||||
| 	return {name, f}; | ||||
| } | ||||
| 
 | ||||
| set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion) | ||||
| std::set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion) | ||||
| { | ||||
| 	// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name
 | ||||
| 	// basefee for VMs before london.
 | ||||
| @ -122,20 +122,20 @@ set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion) | ||||
| 
 | ||||
| 	// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name
 | ||||
| 	// prevrandao for VMs before paris.
 | ||||
| 	auto prevRandaoException = [&](string const& _instrName) -> bool | ||||
| 	auto prevRandaoException = [&](std::string const& _instrName) -> bool | ||||
| 	{ | ||||
| 		// Using string comparison as the opcode is the same as for "difficulty"
 | ||||
| 		return _instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris(); | ||||
| 	}; | ||||
| 
 | ||||
| 	set<YulString> reserved; | ||||
| 	std::set<YulString> reserved; | ||||
| 	for (auto const& instr: evmasm::c_instructions) | ||||
| 	{ | ||||
| 		string name = toLower(instr.first); | ||||
| 		std::string name = toLower(instr.first); | ||||
| 		if (!baseFeeException(instr.second) && !prevRandaoException(name)) | ||||
| 			reserved.emplace(name); | ||||
| 	} | ||||
| 	reserved += vector<YulString>{ | ||||
| 	reserved += std::vector<YulString>{ | ||||
| 		"linkersymbol"_yulstring, | ||||
| 		"datasize"_yulstring, | ||||
| 		"dataoffset"_yulstring, | ||||
| @ -146,19 +146,19 @@ set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion) | ||||
| 	return reserved; | ||||
| } | ||||
| 
 | ||||
| map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVersion, bool _objectAccess) | ||||
| std::map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVersion, bool _objectAccess) | ||||
| { | ||||
| 
 | ||||
| 	// Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris.
 | ||||
| 	auto prevRandaoException = [&](string const& _instrName) -> bool | ||||
| 	auto prevRandaoException = [&](std::string const& _instrName) -> bool | ||||
| 	{ | ||||
| 		return (_instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris()) || (_instrName == "difficulty" && _evmVersion >= langutil::EVMVersion::paris()); | ||||
| 	}; | ||||
| 
 | ||||
| 	map<YulString, BuiltinFunctionForEVM> builtins; | ||||
| 	std::map<YulString, BuiltinFunctionForEVM> builtins; | ||||
| 	for (auto const& instr: evmasm::c_instructions) | ||||
| 	{ | ||||
| 		string name = toLower(instr.first); | ||||
| 		std::string name = toLower(instr.first); | ||||
| 		auto const opcode = instr.second; | ||||
| 
 | ||||
| 		if ( | ||||
| @ -198,7 +198,7 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe | ||||
| 				BuiltinContext& | ||||
| 			) { | ||||
| 				yulAssert(_call.arguments.size() == 1, ""); | ||||
| 				Literal const* literal = get_if<Literal>(&_call.arguments.front()); | ||||
| 				Literal const* literal = std::get_if<Literal>(&_call.arguments.front()); | ||||
| 				yulAssert(literal, ""); | ||||
| 				_assembly.appendConstant(valueOfLiteral(*literal)); | ||||
| 			}) | ||||
| @ -217,10 +217,10 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe | ||||
| 				_assembly.appendAssemblySize(); | ||||
| 			else | ||||
| 			{ | ||||
| 				vector<size_t> subIdPath = | ||||
| 			std::vector<size_t> subIdPath = | ||||
| 					_context.subIDs.count(dataName) == 0 ? | ||||
| 						_context.currentObject->pathToSubObject(dataName) : | ||||
| 						vector<size_t>{_context.subIDs.at(dataName)}; | ||||
| 						std::vector<size_t>{_context.subIDs.at(dataName)}; | ||||
| 				yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); | ||||
| 				_assembly.appendDataSize(subIdPath); | ||||
| 			} | ||||
| @ -238,10 +238,10 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe | ||||
| 				_assembly.appendConstant(0); | ||||
| 			else | ||||
| 			{ | ||||
| 				vector<size_t> subIdPath = | ||||
| 			std::vector<size_t> subIdPath = | ||||
| 					_context.subIDs.count(dataName) == 0 ? | ||||
| 						_context.currentObject->pathToSubObject(dataName) : | ||||
| 						vector<size_t>{_context.subIDs.at(dataName)}; | ||||
| 						std::vector<size_t>{_context.subIDs.at(dataName)}; | ||||
| 				yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">."); | ||||
| 				_assembly.appendDataOffset(subIdPath); | ||||
| 			} | ||||
| @ -295,9 +295,9 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe | ||||
| 	return builtins; | ||||
| } | ||||
| 
 | ||||
| regex const& verbatimPattern() | ||||
| std::regex const& verbatimPattern() | ||||
| { | ||||
| 	regex static const pattern{"verbatim_([1-9]?[0-9])i_([1-9]?[0-9])o"}; | ||||
| 	std::regex static const pattern{"verbatim_([1-9]?[0-9])i_([1-9]?[0-9])o"}; | ||||
| 	return pattern; | ||||
| } | ||||
| 
 | ||||
| @ -316,7 +316,7 @@ BuiltinFunctionForEVM const* EVMDialect::builtin(YulString _name) const | ||||
| { | ||||
| 	if (m_objectAccess) | ||||
| 	{ | ||||
| 		smatch match; | ||||
| 		std::smatch match; | ||||
| 		if (regex_match(_name.str(), match, verbatimPattern())) | ||||
| 			return verbatimFunction(stoul(match[1]), stoul(match[2])); | ||||
| 	} | ||||
| @ -337,19 +337,19 @@ bool EVMDialect::reservedIdentifier(YulString _name) const | ||||
| 
 | ||||
| EVMDialect const& EVMDialect::strictAssemblyForEVM(langutil::EVMVersion _version) | ||||
| { | ||||
| 	static map<langutil::EVMVersion, unique_ptr<EVMDialect const>> dialects; | ||||
| 	static std::map<langutil::EVMVersion, std::unique_ptr<EVMDialect const>> dialects; | ||||
| 	static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; | ||||
| 	if (!dialects[_version]) | ||||
| 		dialects[_version] = make_unique<EVMDialect>(_version, false); | ||||
| 		dialects[_version] = std::make_unique<EVMDialect>(_version, false); | ||||
| 	return *dialects[_version]; | ||||
| } | ||||
| 
 | ||||
| EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _version) | ||||
| { | ||||
| 	static map<langutil::EVMVersion, unique_ptr<EVMDialect const>> dialects; | ||||
| 	static std::map<langutil::EVMVersion, std::unique_ptr<EVMDialect const>> dialects; | ||||
| 	static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; | ||||
| 	if (!dialects[_version]) | ||||
| 		dialects[_version] = make_unique<EVMDialect>(_version, true); | ||||
| 		dialects[_version] = std::make_unique<EVMDialect>(_version, true); | ||||
| 	return *dialects[_version]; | ||||
| } | ||||
| 
 | ||||
| @ -374,16 +374,16 @@ SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instructio | ||||
| 
 | ||||
| BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVariables) const | ||||
| { | ||||
| 	pair<size_t, size_t> key{_arguments, _returnVariables}; | ||||
| 	shared_ptr<BuiltinFunctionForEVM const>& function = m_verbatimFunctions[key]; | ||||
| 	std::pair<size_t, size_t> key{_arguments, _returnVariables}; | ||||
| 	std::shared_ptr<BuiltinFunctionForEVM const>& function = m_verbatimFunctions[key]; | ||||
| 	if (!function) | ||||
| 	{ | ||||
| 		BuiltinFunctionForEVM builtinFunction = createFunction( | ||||
| 			"verbatim_" + to_string(_arguments) + "i_" + to_string(_returnVariables) + "o", | ||||
| 			"verbatim_" + std::to_string(_arguments) + "i_" + std::to_string(_returnVariables) + "o", | ||||
| 			1 + _arguments, | ||||
| 			_returnVariables, | ||||
| 			SideEffects::worst(), | ||||
| 			vector<optional<LiteralKind>>{LiteralKind::String} + vector<optional<LiteralKind>>(_arguments), | ||||
| 			std::vector<std::optional<LiteralKind>>{LiteralKind::String} + std::vector<std::optional<LiteralKind>>(_arguments), | ||||
| 			[=]( | ||||
| 				FunctionCall const& _call, | ||||
| 				AbstractAssembly& _assembly, | ||||
| @ -400,7 +400,7 @@ BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, siz | ||||
| 			} | ||||
| 		).second; | ||||
| 		builtinFunction.isMSize = true; | ||||
| 		function = make_shared<BuiltinFunctionForEVM const>(std::move(builtinFunction)); | ||||
| 		function = std::make_shared<BuiltinFunctionForEVM const>(std::move(builtinFunction)); | ||||
| 	} | ||||
| 	return function.get(); | ||||
| } | ||||
| @ -501,9 +501,9 @@ BuiltinFunctionForEVM const* EVMDialectTyped::equalityFunction(YulString _type) | ||||
| 
 | ||||
| EVMDialectTyped const& EVMDialectTyped::instance(langutil::EVMVersion _version) | ||||
| { | ||||
| 	static map<langutil::EVMVersion, unique_ptr<EVMDialectTyped const>> dialects; | ||||
| 	static std::map<langutil::EVMVersion, std::unique_ptr<EVMDialectTyped const>> dialects; | ||||
| 	static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }}; | ||||
| 	if (!dialects[_version]) | ||||
| 		dialects[_version] = make_unique<EVMDialectTyped>(_version, true); | ||||
| 		dialects[_version] = std::make_unique<EVMDialectTyped>(_version, true); | ||||
| 	return *dialects[_version]; | ||||
| } | ||||
|  | ||||
| @ -31,7 +31,6 @@ | ||||
| 
 | ||||
| #include <libsolutil/CommonData.h> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| using namespace solidity::util; | ||||
| @ -52,7 +51,7 @@ bigint GasMeter::combineCosts(std::pair<bigint, bigint> _costs) const | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| pair<bigint, bigint> GasMeterVisitor::costs( | ||||
| std::pair<bigint, bigint> GasMeterVisitor::costs( | ||||
| 	Expression const& _expression, | ||||
| 	EVMDialect const& _dialect, | ||||
| 	bool _isCreation | ||||
| @ -63,7 +62,7 @@ pair<bigint, bigint> GasMeterVisitor::costs( | ||||
| 	return {gmv.m_runGas, gmv.m_dataGas}; | ||||
| } | ||||
| 
 | ||||
| pair<bigint, bigint> GasMeterVisitor::instructionCosts( | ||||
| std::pair<bigint, bigint> GasMeterVisitor::instructionCosts( | ||||
| 	evmasm::Instruction _instruction, | ||||
| 	EVMDialect const& _dialect, | ||||
| 	bool _isCreation | ||||
|  | ||||
| @ -33,7 +33,6 @@ | ||||
| #include <boost/algorithm/string.hpp> | ||||
| 
 | ||||
| using namespace solidity::yul; | ||||
| using namespace std; | ||||
| 
 | ||||
| void EVMObjectCompiler::compile( | ||||
| 	Object& _object, | ||||
| @ -91,12 +90,12 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) | ||||
| 		); | ||||
| 		if (!stackErrors.empty()) | ||||
| 		{ | ||||
| 			vector<FunctionCall*> memoryGuardCalls = FunctionCallFinder::run( | ||||
| 			std::vector<FunctionCall*> memoryGuardCalls = FunctionCallFinder::run( | ||||
| 				*_object.code, | ||||
| 				"memoryguard"_yulstring | ||||
| 			); | ||||
| 			auto stackError = stackErrors.front(); | ||||
| 			string msg = stackError.comment() ? *stackError.comment() : ""; | ||||
| 			std::string msg = stackError.comment() ? *stackError.comment() : ""; | ||||
| 			if (memoryGuardCalls.empty()) | ||||
| 				msg += "\nNo memoryguard was present. " | ||||
| 					"Consider using memory-safe assembly only and annotating it via " | ||||
|  | ||||
| @ -33,7 +33,6 @@ | ||||
| #include <memory> | ||||
| #include <functional> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| using namespace solidity::util; | ||||
| @ -122,14 +121,14 @@ void EthAssemblyAdapter::appendAssemblySize() | ||||
| 	m_assembly.appendProgramSize(); | ||||
| } | ||||
| 
 | ||||
| pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly(bool _creation, string _name) | ||||
| std::pair<std::shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly(bool _creation, std::string _name) | ||||
| { | ||||
| 	shared_ptr<evmasm::Assembly> assembly{make_shared<evmasm::Assembly>(m_assembly.evmVersion(), _creation, std::move(_name))}; | ||||
| 	std::shared_ptr<evmasm::Assembly> assembly{std::make_shared<evmasm::Assembly>(m_assembly.evmVersion(), _creation, std::move(_name))}; | ||||
| 	auto sub = m_assembly.newSub(assembly); | ||||
| 	return {make_shared<EthAssemblyAdapter>(*assembly), static_cast<size_t>(sub.data())}; | ||||
| 	return {std::make_shared<EthAssemblyAdapter>(*assembly), static_cast<size_t>(sub.data())}; | ||||
| } | ||||
| 
 | ||||
| void EthAssemblyAdapter::appendDataOffset(vector<AbstractAssembly::SubID> const& _subPath) | ||||
| void EthAssemblyAdapter::appendDataOffset(std::vector<AbstractAssembly::SubID> const& _subPath) | ||||
| { | ||||
| 	if (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end()) | ||||
| 	{ | ||||
| @ -141,7 +140,7 @@ void EthAssemblyAdapter::appendDataOffset(vector<AbstractAssembly::SubID> const& | ||||
| 	m_assembly.pushSubroutineOffset(m_assembly.encodeSubPath(_subPath)); | ||||
| } | ||||
| 
 | ||||
| void EthAssemblyAdapter::appendDataSize(vector<AbstractAssembly::SubID> const& _subPath) | ||||
| void EthAssemblyAdapter::appendDataSize(std::vector<AbstractAssembly::SubID> const& _subPath) | ||||
| { | ||||
| 	if (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end()) | ||||
| 	{ | ||||
|  | ||||
| @ -28,7 +28,6 @@ | ||||
| 
 | ||||
| #include <range/v3/view/iota.hpp> | ||||
| 
 | ||||
| using namespace std; | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| using namespace solidity::util; | ||||
| @ -60,12 +59,12 @@ NoOutputAssembly::LabelID NoOutputAssembly::newLabelId() | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| AbstractAssembly::LabelID NoOutputAssembly::namedLabel(string const&, size_t, size_t, optional<size_t>) | ||||
| AbstractAssembly::LabelID NoOutputAssembly::namedLabel(std::string const&, size_t, size_t, std::optional<size_t>) | ||||
| { | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| void NoOutputAssembly::appendLinkerSymbol(string const&) | ||||
| void NoOutputAssembly::appendLinkerSymbol(std::string const&) | ||||
| { | ||||
| 	yulAssert(false, "Linker symbols not yet implemented."); | ||||
| } | ||||
| @ -98,7 +97,7 @@ void NoOutputAssembly::appendAssemblySize() | ||||
| 	appendInstruction(evmasm::Instruction::PUSH1); | ||||
| } | ||||
| 
 | ||||
| pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(bool, std::string) | ||||
| std::pair<std::shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(bool, std::string) | ||||
| { | ||||
| 	yulAssert(false, "Sub assemblies not implemented."); | ||||
| 	return {}; | ||||
|  | ||||
| @ -38,9 +38,8 @@ | ||||
| 
 | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| using namespace std; | ||||
| 
 | ||||
| vector<StackTooDeepError> OptimizedEVMCodeTransform::run( | ||||
| std::vector<StackTooDeepError> OptimizedEVMCodeTransform::run( | ||||
| 	AbstractAssembly& _assembly, | ||||
| 	AsmAnalysisInfo& _analysisInfo, | ||||
| 	Block const& _block, | ||||
| @ -81,7 +80,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) | ||||
| 		// Assert that we got the correct return label on stack.
 | ||||
| 		if (_call.canContinue) | ||||
| 		{ | ||||
| 			auto const* returnLabelSlot = get_if<FunctionCallReturnLabelSlot>( | ||||
| 			auto const* returnLabelSlot = std::get_if<FunctionCallReturnLabelSlot>( | ||||
| 				&m_stack.at(m_stack.size() - _call.functionCall.get().arguments.size() - 1) | ||||
| 			); | ||||
| 			yulAssert(returnLabelSlot && &returnLabelSlot->call.get() == &_call.functionCall.get(), ""); | ||||
| @ -160,7 +159,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::Assignment const& _assignment) | ||||
| 
 | ||||
| 	// Invalidate occurrences of the assigned variables.
 | ||||
| 	for (auto& currentSlot: m_stack) | ||||
| 		if (VariableSlot const* varSlot = get_if<VariableSlot>(¤tSlot)) | ||||
| 		if (VariableSlot const* varSlot = std::get_if<VariableSlot>(¤tSlot)) | ||||
| 			if (util::contains(_assignment.variables, *varSlot)) | ||||
| 				currentSlot = JunkSlot{}; | ||||
| 
 | ||||
| @ -185,8 +184,8 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( | ||||
| 	m_dfg(_dfg), | ||||
| 	m_stackLayout(_stackLayout), | ||||
| 	m_functionLabels([&](){ | ||||
| 		map<CFG::FunctionInfo const*, AbstractAssembly::LabelID> functionLabels; | ||||
| 		set<YulString> assignedFunctionNames; | ||||
| 		std::map<CFG::FunctionInfo const*, AbstractAssembly::LabelID> functionLabels; | ||||
| 		std::set<YulString> assignedFunctionNames; | ||||
| 		for (Scope::Function const* function: m_dfg.functions) | ||||
| 		{ | ||||
| 			CFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(function); | ||||
| @ -199,7 +198,7 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( | ||||
| 					function->name.str(), | ||||
| 					function->arguments.size(), | ||||
| 					function->returns.size(), | ||||
| 					functionInfo.debugData ? functionInfo.debugData->astID : nullopt | ||||
| 					functionInfo.debugData ? functionInfo.debugData->astID : std::nullopt | ||||
| 				) : | ||||
| 				m_assembly.newLabelId(); | ||||
| 		} | ||||
| @ -212,7 +211,7 @@ void OptimizedEVMCodeTransform::assertLayoutCompatibility(Stack const& _currentS | ||||
| { | ||||
| 	yulAssert(_currentStack.size() == _desiredStack.size(), ""); | ||||
| 	for (auto&& [currentSlot, desiredSlot]: ranges::zip_view(_currentStack, _desiredStack)) | ||||
| 		yulAssert(holds_alternative<JunkSlot>(desiredSlot) || currentSlot == desiredSlot, ""); | ||||
| 		yulAssert(std::holds_alternative<JunkSlot>(desiredSlot) || currentSlot == desiredSlot, ""); | ||||
| } | ||||
| 
 | ||||
| AbstractAssembly::LabelID OptimizedEVMCodeTransform::getFunctionLabel(Scope::Function const& _function) | ||||
| @ -224,15 +223,15 @@ void OptimizedEVMCodeTransform::validateSlot(StackSlot const& _slot, Expression | ||||
| { | ||||
| 	std::visit(util::GenericVisitor{ | ||||
| 		[&](yul::Literal const& _literal) { | ||||
| 			auto* literalSlot = get_if<LiteralSlot>(&_slot); | ||||
| 			auto* literalSlot = std::get_if<LiteralSlot>(&_slot); | ||||
| 			yulAssert(literalSlot && valueOfLiteral(_literal) == literalSlot->value, ""); | ||||
| 		}, | ||||
| 		[&](yul::Identifier const& _identifier) { | ||||
| 			auto* variableSlot = get_if<VariableSlot>(&_slot); | ||||
| 			auto* variableSlot = std::get_if<VariableSlot>(&_slot); | ||||
| 			yulAssert(variableSlot && variableSlot->variable.get().name == _identifier.name, ""); | ||||
| 		}, | ||||
| 		[&](yul::FunctionCall const& _call) { | ||||
| 			auto* temporarySlot = get_if<TemporarySlot>(&_slot); | ||||
| 			auto* temporarySlot = std::get_if<TemporarySlot>(&_slot); | ||||
| 			yulAssert(temporarySlot && &temporarySlot->call.get() == &_call && temporarySlot->index == 0, ""); | ||||
| 		} | ||||
| 	}, _expression); | ||||
| @ -267,10 +266,10 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr<DebugData cons | ||||
| 				StackSlot const& deepSlot = m_stack.at(m_stack.size() - _i - 1); | ||||
| 				YulString varNameDeep = slotVariableName(deepSlot); | ||||
| 				YulString varNameTop = slotVariableName(m_stack.back()); | ||||
| 				string msg = | ||||
| 				std::string msg = | ||||
| 					"Cannot swap " + (varNameDeep.empty() ? "Slot " + stackSlotToString(deepSlot) : "Variable " + varNameDeep.str()) + | ||||
| 					" with " + (varNameTop.empty() ? "Slot " + stackSlotToString(m_stack.back()) : "Variable " + varNameTop.str()) + | ||||
| 					": too deep in the stack by " + to_string(deficit) + " slots in " + stackToString(m_stack); | ||||
| 					": too deep in the stack by " + std::to_string(deficit) + " slots in " + stackToString(m_stack); | ||||
| 				m_stackErrors.emplace_back(StackTooDeepError( | ||||
| 					m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulString{}, | ||||
| 					varNameDeep.empty() ? varNameTop : varNameDeep, | ||||
| @ -297,9 +296,9 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr<DebugData cons | ||||
| 				{ | ||||
| 					int deficit = static_cast<int>(*depth - 15); | ||||
| 					YulString varName = slotVariableName(_slot); | ||||
| 					string msg = | ||||
| 					std::string msg = | ||||
| 						(varName.empty() ? "Slot " + stackSlotToString(_slot) : "Variable " + varName.str()) | ||||
| 						+ " is " + to_string(*depth - 15) + " too deep in the stack " + stackToString(m_stack); | ||||
| 						+ " is " + std::to_string(*depth - 15) + " too deep in the stack " + stackToString(m_stack); | ||||
| 					m_stackErrors.emplace_back(StackTooDeepError( | ||||
| 						m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulString{}, | ||||
| 						varName, | ||||
| @ -503,9 +502,9 @@ void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block) | ||||
| 		[&](CFG::BasicBlock::Terminated const&) | ||||
| 		{ | ||||
| 			yulAssert(!_block.operations.empty()); | ||||
| 			if (CFG::BuiltinCall const* builtinCall = get_if<CFG::BuiltinCall>(&_block.operations.back().operation)) | ||||
| 			if (CFG::BuiltinCall const* builtinCall = std::get_if<CFG::BuiltinCall>(&_block.operations.back().operation)) | ||||
| 				yulAssert(builtinCall->builtin.get().controlFlowSideEffects.terminatesOrReverts(), ""); | ||||
| 			else if (CFG::FunctionCall const* functionCall = get_if<CFG::FunctionCall>(&_block.operations.back().operation)) | ||||
| 			else if (CFG::FunctionCall const* functionCall = std::get_if<CFG::FunctionCall>(&_block.operations.back().operation)) | ||||
| 				yulAssert(!functionCall->canContinue); | ||||
| 			else | ||||
| 				yulAssert(false); | ||||
|  | ||||
| @ -46,7 +46,6 @@ | ||||
| 
 | ||||
| using namespace solidity; | ||||
| using namespace solidity::yul; | ||||
| using namespace std; | ||||
| 
 | ||||
| StackLayout StackLayoutGenerator::run(CFG const& _cfg) | ||||
| { | ||||
| @ -59,9 +58,9 @@ StackLayout StackLayoutGenerator::run(CFG const& _cfg) | ||||
| 	return stackLayout; | ||||
| } | ||||
| 
 | ||||
| map<YulString, vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg) | ||||
| std::map<YulString, std::vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg) | ||||
| { | ||||
| 	map<YulString, vector<StackLayoutGenerator::StackTooDeep>> stackTooDeepErrors; | ||||
| 	std::map<YulString, std::vector<StackLayoutGenerator::StackTooDeep>> stackTooDeepErrors; | ||||
| 	stackTooDeepErrors[YulString{}] = reportStackTooDeep(_cfg, YulString{}); | ||||
| 	for (auto const& function: _cfg.functions) | ||||
| 		if (auto errors = reportStackTooDeep(_cfg, function->name); !errors.empty()) | ||||
| @ -69,7 +68,7 @@ map<YulString, vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator: | ||||
| 	return stackTooDeepErrors; | ||||
| } | ||||
| 
 | ||||
| vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulString _functionName) | ||||
| std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulString _functionName) | ||||
| { | ||||
| 	StackLayout stackLayout; | ||||
| 	CFG::FunctionInfo const* functionInfo = nullptr; | ||||
| @ -98,14 +97,14 @@ StackLayoutGenerator::StackLayoutGenerator(StackLayout& _layout, CFG::FunctionIn | ||||
| namespace | ||||
| { | ||||
| /// @returns all stack too deep errors that would occur when shuffling @a _source to @a _target.
 | ||||
| vector<StackLayoutGenerator::StackTooDeep> findStackTooDeep(Stack const& _source, Stack const& _target) | ||||
| std::vector<StackLayoutGenerator::StackTooDeep> findStackTooDeep(Stack const& _source, Stack const& _target) | ||||
| { | ||||
| 	Stack currentStack = _source; | ||||
| 	vector<StackLayoutGenerator::StackTooDeep> stackTooDeepErrors; | ||||
| 	std::vector<StackLayoutGenerator::StackTooDeep> stackTooDeepErrors; | ||||
| 	auto getVariableChoices = [](auto&& _range) { | ||||
| 		vector<YulString> result; | ||||
| 		std::vector<YulString> result; | ||||
| 		for (auto const& slot: _range) | ||||
| 			if (auto const* variableSlot = get_if<VariableSlot>(&slot)) | ||||
| 			if (auto const* variableSlot = std::get_if<VariableSlot>(&slot)) | ||||
| 				if (!util::contains(result, variableSlot->variable.get().name)) | ||||
| 					result.push_back(variableSlot->variable.get().name); | ||||
| 		return result; | ||||
| @ -160,7 +159,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla | ||||
| 	// PreviousSlot{0}, ..., PreviousSlot{n}, [output<0>], ..., [output<m>]
 | ||||
| 	auto layout = ranges::views::iota(0u, preOperationLayoutSize) | | ||||
| 		ranges::views::transform([](size_t _index) { return PreviousSlot{_index}; }) | | ||||
| 		ranges::to<vector<variant<PreviousSlot, StackSlot>>>; | ||||
| 		ranges::to<std::vector<std::variant<PreviousSlot, StackSlot>>>; | ||||
| 	layout += _operationOutput; | ||||
| 
 | ||||
| 	// Shortcut for trivial case.
 | ||||
| @ -171,23 +170,23 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla | ||||
| 	// that are aware of PreviousSlot's.
 | ||||
| 	struct ShuffleOperations | ||||
| 	{ | ||||
| 		vector<variant<PreviousSlot, StackSlot>>& layout; | ||||
| 		std::vector<std::variant<PreviousSlot, StackSlot>>& layout; | ||||
| 		Stack const& post; | ||||
| 		std::set<StackSlot> outputs; | ||||
| 		Multiplicity multiplicity; | ||||
| 		Callable generateSlotOnTheFly; | ||||
| 		ShuffleOperations( | ||||
| 			vector<variant<PreviousSlot, StackSlot>>& _layout, | ||||
| 			std::vector<std::variant<PreviousSlot, StackSlot>>& _layout, | ||||
| 			Stack const& _post, | ||||
| 			Callable _generateSlotOnTheFly | ||||
| 		): layout(_layout), post(_post), generateSlotOnTheFly(_generateSlotOnTheFly) | ||||
| 		{ | ||||
| 			for (auto const& layoutSlot: layout) | ||||
| 				if (StackSlot const* slot = get_if<StackSlot>(&layoutSlot)) | ||||
| 				if (StackSlot const* slot = std::get_if<StackSlot>(&layoutSlot)) | ||||
| 					outputs.insert(*slot); | ||||
| 
 | ||||
| 			for (auto const& layoutSlot: layout) | ||||
| 				if (StackSlot const* slot = get_if<StackSlot>(&layoutSlot)) | ||||
| 				if (StackSlot const* slot = std::get_if<StackSlot>(&layoutSlot)) | ||||
| 					--multiplicity[*slot]; | ||||
| 			for (auto&& slot: post) | ||||
| 				if (outputs.count(slot) || generateSlotOnTheFly(slot)) | ||||
| @ -235,7 +234,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla | ||||
| 		} | ||||
| 		void swap(size_t _i) | ||||
| 		{ | ||||
| 			yulAssert(!holds_alternative<PreviousSlot>(layout.at(layout.size() - _i - 1)) || !holds_alternative<PreviousSlot>(layout.back()), ""); | ||||
| 			yulAssert(!std::holds_alternative<PreviousSlot>(layout.at(layout.size() - _i - 1)) || !std::holds_alternative<PreviousSlot>(layout.back()), ""); | ||||
| 			std::swap(layout.at(layout.size() -  _i - 1), layout.back()); | ||||
| 		} | ||||
| 		size_t sourceSize() { return layout.size(); } | ||||
| @ -250,7 +249,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla | ||||
| 	// output in place. The resulting permutation of the PreviousSlot yields the ideal positions of slots
 | ||||
| 	// before the operation, i.e. if PreviousSlot{2} is at a position at which _post contains VariableSlot{"tmp"},
 | ||||
| 	// then we want the variable tmp in the slot at offset 2 in the layout before the operation.
 | ||||
| 	vector<optional<StackSlot>> idealLayout(_post.size(), nullopt); | ||||
| 	std::vector<std::optional<StackSlot>> idealLayout(_post.size(), std::nullopt); | ||||
| 	for (auto&& [slot, idealPosition]: ranges::zip_view(_post, layout)) | ||||
| 		if (PreviousSlot* previousSlot = std::get_if<PreviousSlot>(&idealPosition)) | ||||
| 			idealLayout.at(previousSlot->slot) = slot; | ||||
| @ -261,7 +260,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla | ||||
| 
 | ||||
| 	yulAssert(idealLayout.size() == preOperationLayoutSize, ""); | ||||
| 
 | ||||
| 	return idealLayout | ranges::views::transform([](optional<StackSlot> s) { | ||||
| 	return idealLayout | ranges::views::transform([](std::optional<StackSlot> s) { | ||||
| 		yulAssert(s, ""); | ||||
| 		return *s; | ||||
| 	}) | ranges::to<Stack>; | ||||
| @ -271,7 +270,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla | ||||
| Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG::Operation const& _operation, bool _aggressiveStackCompression) | ||||
| { | ||||
| 	// Enable aggressive stack compression for recursive calls.
 | ||||
| 	if (auto const* functionCall = get_if<CFG::FunctionCall>(&_operation.operation)) | ||||
| 	if (auto const* functionCall = std::get_if<CFG::FunctionCall>(&_operation.operation)) | ||||
| 		if (functionCall->recursive) | ||||
| 			_aggressiveStackCompression = true; | ||||
| 
 | ||||
| @ -285,9 +284,9 @@ Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG | ||||
| 	Stack stack = createIdealLayout(_operation.output, _exitStack, generateSlotOnTheFly); | ||||
| 
 | ||||
| 	// Make sure the resulting previous slots do not overlap with any assignmed variables.
 | ||||
| 	if (auto const* assignment = get_if<CFG::Assignment>(&_operation.operation)) | ||||
| 	if (auto const* assignment = std::get_if<CFG::Assignment>(&_operation.operation)) | ||||
| 		for (auto& stackSlot: stack) | ||||
| 			if (auto const* varSlot = get_if<VariableSlot>(&stackSlot)) | ||||
| 			if (auto const* varSlot = std::get_if<VariableSlot>(&stackSlot)) | ||||
| 				yulAssert(!util::contains(assignment->variables, *varSlot), ""); | ||||
| 
 | ||||
| 	// Since stack+_operation.output can be easily shuffled to _exitLayout, the desired layout before the operation
 | ||||
| @ -335,11 +334,11 @@ Stack StackLayoutGenerator::propagateStackThroughBlock(Stack _exitStack, CFG::Ba | ||||
| 
 | ||||
| void StackLayoutGenerator::processEntryPoint(CFG::BasicBlock const& _entry, CFG::FunctionInfo const* _functionInfo) | ||||
| { | ||||
| 	list<CFG::BasicBlock const*> toVisit{&_entry}; | ||||
| 	set<CFG::BasicBlock const*> visited; | ||||
| 	std::list<CFG::BasicBlock const*> toVisit{&_entry}; | ||||
| 	std::set<CFG::BasicBlock const*> visited; | ||||
| 
 | ||||
| 	// TODO: check whether visiting only a subset of these in the outer iteration below is enough.
 | ||||
| 	list<pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps = collectBackwardsJumps(_entry); | ||||
| 	std::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps = collectBackwardsJumps(_entry); | ||||
| 
 | ||||
| 	while (!toVisit.empty()) | ||||
| 	{ | ||||
| @ -407,10 +406,10 @@ void StackLayoutGenerator::processEntryPoint(CFG::BasicBlock const& _entry, CFG: | ||||
| 	fillInJunk(_entry, _functionInfo); | ||||
| } | ||||
| 
 | ||||
| optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies( | ||||
| std::optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies( | ||||
| 	CFG::BasicBlock const& _block, | ||||
| 	set<CFG::BasicBlock const*> const& _visited, | ||||
| 	list<CFG::BasicBlock const*>& _toVisit | ||||
| 	std::set<CFG::BasicBlock const*> const& _visited, | ||||
| 	std::list<CFG::BasicBlock const*>& _toVisit | ||||
| ) const | ||||
| { | ||||
| 	return std::visit(util::GenericVisitor{ | ||||
| @ -434,7 +433,7 @@ optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies( | ||||
| 				return m_layout.blockInfos.at(_jump.target).entryLayout; | ||||
| 			// Otherwise stage the jump target for visit and defer the current block.
 | ||||
| 			_toVisit.emplace_front(_jump.target); | ||||
| 			return nullopt; | ||||
| 			return std::nullopt; | ||||
| 		}, | ||||
| 		[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump) -> std::optional<Stack> | ||||
| 		{ | ||||
| @ -456,7 +455,7 @@ optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies( | ||||
| 				_toVisit.emplace_front(_conditionalJump.zero); | ||||
| 			if (!nonZeroVisited) | ||||
| 				_toVisit.emplace_front(_conditionalJump.nonZero); | ||||
| 			return nullopt; | ||||
| 			return std::nullopt; | ||||
| 		}, | ||||
| 		[&](CFG::BasicBlock::FunctionReturn const& _functionReturn) -> std::optional<Stack> | ||||
| 		{ | ||||
| @ -476,9 +475,9 @@ optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies( | ||||
| 	}, _block.exit); | ||||
| } | ||||
| 
 | ||||
| list<pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> StackLayoutGenerator::collectBackwardsJumps(CFG::BasicBlock const& _entry) const | ||||
| std::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> StackLayoutGenerator::collectBackwardsJumps(CFG::BasicBlock const& _entry) const | ||||
| { | ||||
| 	list<pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps; | ||||
| 	std::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps; | ||||
| 	util::BreadthFirstSearch<CFG::BasicBlock const*>{{&_entry}}.run([&](CFG::BasicBlock const* _block, auto _addChild) { | ||||
| 		std::visit(util::GenericVisitor{ | ||||
| 			[&](CFG::BasicBlock::MainExit const&) {}, | ||||
| @ -576,7 +575,7 @@ Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _sta | ||||
| 		if (!util::contains(candidate, slot)) | ||||
| 			candidate.emplace_back(slot); | ||||
| 	cxx20::erase_if(candidate, [](StackSlot const& slot) { | ||||
| 		return holds_alternative<LiteralSlot>(slot) || holds_alternative<FunctionCallReturnLabelSlot>(slot); | ||||
| 		return std::holds_alternative<LiteralSlot>(slot) || std::holds_alternative<FunctionCallReturnLabelSlot>(slot); | ||||
| 	}); | ||||
| 
 | ||||
| 	auto evaluate = [&](Stack const& _candidate) -> size_t { | ||||
| @ -633,9 +632,9 @@ Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _sta | ||||
| 	return commonPrefix + bestCandidate; | ||||
| } | ||||
| 
 | ||||
| vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG::BasicBlock const& _entry) const | ||||
| std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG::BasicBlock const& _entry) const | ||||
| { | ||||
| 	vector<StackTooDeep> stackTooDeepErrors; | ||||
| 	std::vector<StackTooDeep> stackTooDeepErrors; | ||||
| 	util::BreadthFirstSearch<CFG::BasicBlock const*> breadthFirstSearch{{&_entry}}; | ||||
| 	breadthFirstSearch.run([&](CFG::BasicBlock const* _block, auto _addChild) { | ||||
| 		Stack currentStack = m_layout.blockInfos.at(_block).entryLayout; | ||||
| @ -683,7 +682,7 @@ vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooD | ||||
| 
 | ||||
| Stack StackLayoutGenerator::compressStack(Stack _stack) | ||||
| { | ||||
| 	optional<size_t> firstDupOffset; | ||||
| 	std::optional<size_t> firstDupOffset; | ||||
| 	do | ||||
| 	{ | ||||
| 		if (firstDupOffset) | ||||
| @ -768,8 +767,8 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi | ||||
| 				{ | ||||
| 					// This has to be a previously unassigned return variable.
 | ||||
| 					// We at least sanity-check that it is among the return variables at all.
 | ||||
| 					yulAssert(m_currentFunctionInfo && holds_alternative<VariableSlot>(_slot)); | ||||
| 					yulAssert(util::contains(m_currentFunctionInfo->returnVariables, get<VariableSlot>(_slot))); | ||||
| 					yulAssert(m_currentFunctionInfo && std::holds_alternative<VariableSlot>(_slot)); | ||||
| 					yulAssert(util::contains(m_currentFunctionInfo->returnVariables, std::get<VariableSlot>(_slot))); | ||||
| 					// Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference
 | ||||
| 					// will not matter here.
 | ||||
| 					opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(0), langutil::EVMVersion());; | ||||
|  | ||||
| @ -34,6 +34,7 @@ NAMESPACE_STD_FREE_FILES=( | ||||
|     libsolidity/lsp/* | ||||
|     libsolidity/parsing/* | ||||
|     libsolutil/* | ||||
|     libyul/backends/evm/* | ||||
|     solc/* | ||||
| ) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user