diff options
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 2 | ||||
-rw-r--r-- | libsolidity/ast/AST.cpp | 18 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 3 | ||||
-rw-r--r-- | libsolidity/codegen/ContractCompiler.cpp | 18 | ||||
-rw-r--r-- | libsolidity/codegen/ExpressionCompiler.cpp | 1 |
5 files changed, 34 insertions, 8 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index b276a2d4..1563467c 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1886,7 +1886,7 @@ void TypeChecker::expectType(Expression const& _expression, Type const& _expecte { auto literal = dynamic_cast<Literal const*>(&_expression); - if (literal && !boost::starts_with(literal->value(), "0x")) + if (literal && !literal->isHexNumber()) m_errorReporter.warning( _expression.location(), "Decimal literal assigned to bytesXX variable will be left-aligned. " diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index b929b6fe..403f4b79 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -530,20 +530,26 @@ IdentifierAnnotation& Identifier::annotation() const return dynamic_cast<IdentifierAnnotation&>(*m_annotation); } +bool Literal::isHexNumber() const +{ + if (token() != Token::Number) + return false; + return boost::starts_with(value(), "0x"); +} + bool Literal::looksLikeAddress() const { if (subDenomination() != SubDenomination::None) return false; - if (token() != Token::Number) + + if (!isHexNumber()) return false; - string lit = value(); - return lit.substr(0, 2) == "0x" && abs(int(lit.length()) - 42) <= 1; + return abs(int(value().length()) - 42) <= 1; } bool Literal::passesAddressChecksum() const { - string lit = value(); - solAssert(lit.substr(0, 2) == "0x", "Expected hex prefix"); - return dev::passesAddressChecksum(lit, true); + solAssert(isHexNumber(), "Expected hex number"); + return dev::passesAddressChecksum(value(), true); } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 83572692..e8831dc0 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -1590,6 +1590,9 @@ public: SubDenomination subDenomination() const { return m_subDenomination; } + /// @returns true if this is a number with a hex prefix. + bool isHexNumber() const; + /// @returns true if this looks like a checksummed address. bool looksLikeAddress() const; /// @returns true if it passes the address checksum test. diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 977a2c7c..74b07d4d 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -267,13 +267,19 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac m_context << notFound; if (fallback) { + m_context.setStackOffset(0); if (!fallback->isPayable()) appendCallValueCheck(); + // Return tag is used to jump out of the function. eth::AssemblyItem returnTag = m_context.pushNewTag(); fallback->accept(*this); m_context << returnTag; - appendReturnValuePacker(FunctionType(*fallback).returnParameterTypes(), _contract.isLibrary()); + solAssert(FunctionType(*fallback).parameterTypes().empty(), ""); + solAssert(FunctionType(*fallback).returnParameterTypes().empty(), ""); + // Return tag gets consumed. + m_context.adjustStackOffset(-1); + m_context << Instruction::STOP; } else m_context.appendRevert(); @@ -285,16 +291,26 @@ void ContractCompiler::appendFunctionSelector(ContractDefinition const& _contrac CompilerContext::LocationSetter locationSetter(m_context, functionType->declaration()); m_context << callDataUnpackerEntryPoints.at(it.first); + m_context.setStackOffset(0); // We have to allow this for libraries, because value of the previous // call is still visible in the delegatecall. if (!functionType->isPayable() && !_contract.isLibrary()) appendCallValueCheck(); + // Return tag is used to jump out of the function. eth::AssemblyItem returnTag = m_context.pushNewTag(); + // Parameter for calldataUnpacker m_context << CompilerUtils::dataStartOffset; appendCalldataUnpacker(functionType->parameterTypes()); m_context.appendJumpTo(m_context.functionEntryLabel(functionType->declaration())); m_context << returnTag; + // Return tag and input parameters get consumed. + m_context.adjustStackOffset( + CompilerUtils(m_context).sizeOnStack(functionType->returnParameterTypes()) - + CompilerUtils(m_context).sizeOnStack(functionType->parameterTypes()) - + 1 + ); + // Consumes the return parameters. appendReturnValuePacker(functionType->returnParameterTypes(), _contract.isLibrary()); } } diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index a65549fd..9d4024c9 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -88,6 +88,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& FunctionType accessorType(_varDecl); TypePointers paramTypes = accessorType.parameterTypes(); + m_context.adjustStackOffset(1 + CompilerUtils::sizeOnStack(paramTypes)); // retrieve the position of the variable auto const& location = m_context.storageLocationOfVariable(_varDecl); |