diff options
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/SyntaxChecker.cpp | 7 | ||||
-rw-r--r-- | libsolidity/interface/GasEstimator.cpp | 9 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.cpp | 19 |
3 files changed, 30 insertions, 5 deletions
diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index 343b4ba8..f648e5b4 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -232,6 +232,13 @@ bool SyntaxChecker::visit(FunctionDefinition const& _function) "Use \"constructor(...) { ... }\" instead." ); } + if (!_function.isImplemented() && !_function.modifiers().empty()) + { + if (v050) + m_errorReporter.syntaxError(_function.location(), "Functions without implementation cannot have modifiers."); + else + m_errorReporter.warning( _function.location(), "Modifiers of functions without implementation are ignored." ); + } return true; } diff --git a/libsolidity/interface/GasEstimator.cpp b/libsolidity/interface/GasEstimator.cpp index 2139395f..a496cc21 100644 --- a/libsolidity/interface/GasEstimator.cpp +++ b/libsolidity/interface/GasEstimator.cpp @@ -136,12 +136,19 @@ GasEstimator::GasConsumption GasEstimator::functionalEstimation( ExpressionClasses& classes = state->expressionClasses(); using Id = ExpressionClasses::Id; using Ids = vector<Id>; + // div(calldataload(0), 1 << 224) equals to hashValue Id hashValue = classes.find(u256(FixedHash<4>::Arith(FixedHash<4>(dev::keccak256(_signature))))); Id calldata = classes.find(Instruction::CALLDATALOAD, Ids{classes.find(u256(0))}); classes.forceEqual(hashValue, Instruction::DIV, Ids{ calldata, - classes.find(u256(1) << (8 * 28)) + classes.find(u256(1) << 224) }); + // lt(calldatasize(), 4) equals to 0 (ignore the shortcut for fallback functions) + classes.forceEqual( + classes.find(u256(0)), + Instruction::LT, + Ids{classes.find(Instruction::CALLDATASIZE), classes.find(u256(4))} + ); } PathGasMeter meter(_items, m_evmVersion); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 18ef740a..2d8ca7d3 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -365,12 +365,13 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader( Token::Value token = m_scanner->currentToken(); if (_allowModifiers && token == Token::Identifier) { - // This can either be a modifier (function declaration) or the name of the - // variable (function type name plus variable). - if ( + // If the name is empty (and this is not a constructor), + // then this can either be a modifier (fallback function declaration) + // or the name of the state variable (function type name plus variable). + if ((result.name->empty() && !result.isConstructor) && ( m_scanner->peekNextToken() == Token::Semicolon || m_scanner->peekNextToken() == Token::Assign - ) + )) // Variable declaration, break here. break; else @@ -380,6 +381,14 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader( { if (result.visibility != Declaration::Visibility::Default) { + // There is the special case of a public state variable of function type. + // Detect this and return early. + if ( + (result.visibility == Declaration::Visibility::External || result.visibility == Declaration::Visibility::Internal) && + result.modifiers.empty() && + (result.name->empty() && !result.isConstructor) + ) + break; parserError(string( "Visibility already specified as \"" + Declaration::visibilityToString(result.visibility) + @@ -429,6 +438,7 @@ ASTPointer<ASTNode> Parser::parseFunctionDefinitionOrFunctionTypeStateVariable(A FunctionHeaderParserResult header = parseFunctionHeader(false, true, _contractName); if ( + header.isConstructor || !header.modifiers.empty() || !header.name->empty() || m_scanner->currentToken() == Token::Semicolon || @@ -794,6 +804,7 @@ ASTPointer<FunctionTypeName> Parser::parseFunctionType() RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this); FunctionHeaderParserResult header = parseFunctionHeader(true, false); + solAssert(!header.isConstructor, "Tried to parse type as constructor."); return nodeFactory.createNode<FunctionTypeName>( header.parameters, header.returnParameters, |