diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index c6b9fcbf5..4a99764c3 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -668,17 +668,18 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) { auto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier); if (ref == _inlineAssembly.annotation().externalReferences.end()) - return numeric_limits::max(); - Declaration const* declaration = ref->second.declaration; + return false; + InlineAssemblyAnnotation::ExternalIdentifierInfo& identifierInfo = ref->second; + Declaration const* declaration = identifierInfo.declaration; solAssert(!!declaration, ""); - bool requiresStorage = ref->second.isSlot || ref->second.isOffset; + bool requiresStorage = identifierInfo.isSlot || identifierInfo.isOffset; if (auto var = dynamic_cast(declaration)) { solAssert(var->type(), "Expected variable type!"); if (var->immutable()) { m_errorReporter.typeError(3773_error, _identifier.location, "Assembly access to immutable variables is not supported."); - return numeric_limits::max(); + return false; } if (var->isConstant()) { @@ -687,17 +688,17 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) if (var && !var->value()) { m_errorReporter.typeError(3224_error, _identifier.location, "Constant has no value."); - return numeric_limits::max(); + return false; } else if (_context == yul::IdentifierContext::LValue) { m_errorReporter.typeError(6252_error, _identifier.location, "Constant variables cannot be assigned to."); - return numeric_limits::max(); + return false; } else if (requiresStorage) { m_errorReporter.typeError(6617_error, _identifier.location, "The suffixes _offset and _slot can only be used on non-constant storage variables."); - return numeric_limits::max(); + return false; } else if (var && var->value() && !var->value()->annotation().type && !dynamic_cast(var->value().get())) { @@ -706,7 +707,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) _identifier.location, "Constant variables with non-literal values cannot be forward referenced from inline assembly." ); - return size_t(-1); + return false; } else if (!var || !type(*var)->isValueType() || ( !dynamic_cast(var->value().get()) && @@ -714,7 +715,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) )) { m_errorReporter.typeError(7615_error, _identifier.location, "Only direct number constants and references to such constants are supported by inline assembly."); - return size_t(-1); + return false; } } @@ -725,33 +726,33 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) if (!var->isStateVariable() && !var->type()->dataStoredIn(DataLocation::Storage)) { m_errorReporter.typeError(3622_error, _identifier.location, "The suffixes _offset and _slot can only be used on storage variables."); - return numeric_limits::max(); + return false; } else if (_context == yul::IdentifierContext::LValue) { if (var->isStateVariable()) { m_errorReporter.typeError(4713_error, _identifier.location, "State variables cannot be assigned to - you have to use \"sstore()\"."); - return numeric_limits::max(); + return false; } - else if (ref->second.isOffset) + else if (identifierInfo.isOffset) { m_errorReporter.typeError(9739_error, _identifier.location, "Only _slot can be assigned to."); - return numeric_limits::max(); + return false; } else - solAssert(ref->second.isSlot, ""); + solAssert(identifierInfo.isSlot, ""); } } else if (!var->isConstant() && var->isStateVariable()) { m_errorReporter.typeError(1408_error, _identifier.location, "Only local variables are supported. To access storage variables, use the _slot and _offset suffixes."); - return numeric_limits::max(); + return false; } else if (var->type()->dataStoredIn(DataLocation::Storage)) { m_errorReporter.typeError(9068_error, _identifier.location, "You have to use the _slot or _offset suffix to access storage reference variables."); - return numeric_limits::max(); + return false; } else if (var->type()->sizeOnStack() != 1) { @@ -759,21 +760,21 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) m_errorReporter.typeError(2370_error, _identifier.location, "Call data elements cannot be accessed directly. Copy to a local variable first or use \"calldataload\" or \"calldatacopy\" with manually determined offsets and sizes."); else m_errorReporter.typeError(9857_error, _identifier.location, "Only types that use one stack slot are supported."); - return numeric_limits::max(); + return false; } } else if (requiresStorage) { m_errorReporter.typeError(7944_error, _identifier.location, "The suffixes _offset and _slot can only be used on storage variables."); - return numeric_limits::max(); + return false; } else if (_context == yul::IdentifierContext::LValue) { if (dynamic_cast(declaration)) - return numeric_limits::max(); + return false; m_errorReporter.typeError(1990_error, _identifier.location, "Only local variables can be assigned to in inline assembly."); - return numeric_limits::max(); + return false; } if (_context == yul::IdentifierContext::RValue) @@ -782,7 +783,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) if (dynamic_cast(declaration)) { m_errorReporter.declarationError(2025_error, _identifier.location, "Access to functions is not allowed in inline assembly."); - return numeric_limits::max(); + return false; } else if (dynamic_cast(declaration)) { @@ -792,14 +793,14 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) if (!contract->isLibrary()) { m_errorReporter.typeError(4977_error, _identifier.location, "Expected a library."); - return numeric_limits::max(); + return false; } } else - return numeric_limits::max(); + return false; } - ref->second.valueSize = 1; - return size_t(1); + identifierInfo.valueSize = 1; + return true; }; solAssert(!_inlineAssembly.annotation().analysisInfo, ""); _inlineAssembly.annotation().analysisInfo = make_shared(); diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index fea449f7f..3af9a7c94 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -384,12 +384,11 @@ void CompilerContext::appendInlineAssembly( yul::Identifier const& _identifier, yul::IdentifierContext, bool _insideFunction - ) -> size_t + ) -> bool { if (_insideFunction) - return numeric_limits::max(); - auto it = std::find(_localVariables.begin(), _localVariables.end(), _identifier.name.str()); - return it == _localVariables.end() ? numeric_limits::max() : 1; + return false; + return contains(_localVariables, _identifier.name.str()); }; identifierAccess.generateCode = [&]( yul::Identifier const& _identifier, diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 07db82095..eeb80263e 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -132,17 +132,11 @@ vector AsmAnalyzer::operator()(Identifier const& _identifier) } else { - bool found = false; - if (m_resolver) - { - bool insideFunction = m_currentScope->insideFunction(); - size_t stackSize = m_resolver(_identifier, yul::IdentifierContext::RValue, insideFunction); - if (stackSize != numeric_limits::max()) - { - found = true; - yulAssert(stackSize == 1, "Invalid stack size of external reference."); - } - } + bool found = m_resolver && m_resolver( + _identifier, + yul::IdentifierContext::RValue, + m_currentScope->insideFunction() + ); if (!found && watcher.ok()) // Only add an error message if the callback did not do it. m_errorReporter.declarationError(8198_error, _identifier.location, "Identifier not found."); @@ -478,12 +472,10 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulString _valueT else if (m_resolver) { bool insideFunction = m_currentScope->insideFunction(); - size_t variableSize = m_resolver(_variable, yul::IdentifierContext::LValue, insideFunction); - if (variableSize != numeric_limits::max()) + if (m_resolver(_variable, yul::IdentifierContext::LValue, insideFunction)) { found = true; variableType = &m_dialect.defaultType; - yulAssert(variableSize == 1, "Invalid stack size of external reference."); } } diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index 2f86270b0..b46c2f734 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -118,7 +118,7 @@ enum class IdentifierContext { LValue, RValue, VariableDeclaration }; /// to inline assembly (not used in standalone assembly mode). struct ExternalIdentifierAccess { - using Resolver = std::function; + using Resolver = std::function; /// Resolve an external reference given by the identifier in the given context. /// @returns the size of the value (number of stack slots) or size_t(-1) if not found. Resolver resolve;