diff options
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r-- | libsolidity/analysis/StaticAnalyzer.cpp | 36 | ||||
-rw-r--r-- | libsolidity/analysis/SyntaxChecker.cpp | 17 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 106 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.h | 2 | ||||
-rw-r--r-- | libsolidity/analysis/ViewPureChecker.cpp | 38 | ||||
-rw-r--r-- | libsolidity/analysis/ViewPureChecker.h | 1 |
6 files changed, 48 insertions, 152 deletions
diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index c7440565..323282ca 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -150,36 +150,18 @@ bool StaticAnalyzer::visit(ExpressionStatement const& _statement) bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) { - bool const v050 = m_currentContract->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); - if (MagicType const* type = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type.get())) { if (type->kind() == MagicType::Kind::Message && _memberAccess.memberName() == "gas") - { - if (v050) - m_errorReporter.typeError( - _memberAccess.location(), - "\"msg.gas\" has been deprecated in favor of \"gasleft()\"" - ); - else - m_errorReporter.warning( - _memberAccess.location(), - "\"msg.gas\" has been deprecated in favor of \"gasleft()\"" - ); - } - if (type->kind() == MagicType::Kind::Block && _memberAccess.memberName() == "blockhash") - { - if (v050) - m_errorReporter.typeError( - _memberAccess.location(), - "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"" - ); - else - m_errorReporter.warning( - _memberAccess.location(), - "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"" - ); - } + m_errorReporter.typeError( + _memberAccess.location(), + "\"msg.gas\" has been deprecated in favor of \"gasleft()\"" + ); + else if (type->kind() == MagicType::Kind::Block && _memberAccess.memberName() == "blockhash") + m_errorReporter.typeError( + _memberAccess.location(), + "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"" + ); } if (m_nonPayablePublic && !m_library) diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index c408b393..63f8fac3 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -192,15 +192,9 @@ bool SyntaxChecker::visit(Throw const& _throwStatement) bool SyntaxChecker::visit(UnaryOperation const& _operation) { - bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050); - if (_operation.getOperator() == Token::Add) - { - if (v050) - m_errorReporter.syntaxError(_operation.location(), "Use of unary + is deprecated."); - else - m_errorReporter.warning(_operation.location(), "Use of unary + is deprecated."); - } + m_errorReporter.syntaxError(_operation.location(), "Use of unary + is disallowed."); + return true; } @@ -262,14 +256,9 @@ bool SyntaxChecker::visit(FunctionTypeName const& _node) bool SyntaxChecker::visit(VariableDeclaration const& _declaration) { - bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050); - if (!_declaration.typeName()) { - if (v050) - m_errorReporter.syntaxError(_declaration.location(), "Use of the \"var\" keyword is deprecated."); - else - m_errorReporter.warning(_declaration.location(), "Use of the \"var\" keyword is deprecated."); + m_errorReporter.syntaxError(_declaration.location(), "Use of the \"var\" keyword is disallowed."); } return true; } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 500d4123..071ac9fe 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -123,10 +123,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract) m_errorReporter.typeError(function->parameterList().location(), "Fallback function cannot take parameters."); if (!function->returnParameters().empty()) m_errorReporter.typeError(function->returnParameterList()->location(), "Fallback function cannot return values."); - if ( - _contract.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050) && - function->visibility() != FunctionDefinition::Visibility::External - ) + if (function->visibility() != FunctionDefinition::Visibility::External) m_errorReporter.typeError(function->location(), "Fallback function must be defined as \"external\"."); } @@ -335,8 +332,6 @@ void TypeChecker::annotateBaseConstructorArguments( ASTNode const* _argumentNode ) { - bool const v050 = _currentContract.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); - solAssert(_baseConstructor, ""); solAssert(_argumentNode, ""); @@ -365,18 +360,11 @@ void TypeChecker::annotateBaseConstructorArguments( ssl.append("Second constructor call is here: ", previousNode->location()); } - if (v050) - m_errorReporter.declarationError( - *mainLocation, - ssl, - "Base constructor arguments given twice." - ); - else - m_errorReporter.warning( - *mainLocation, - "Base constructor arguments given twice.", - ssl - ); + m_errorReporter.declarationError( + *mainLocation, + ssl, + "Base constructor arguments given twice." + ); } } @@ -460,7 +448,7 @@ void TypeChecker::overrideError(FunctionDefinition const& function, FunctionDefi { m_errorReporter.typeError( function.location(), - SecondarySourceLocation().append("Overriden function is here:", super.location()), + SecondarySourceLocation().append("Overridden function is here:", super.location()), message ); } @@ -758,19 +746,10 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) if (!_variable.value()) m_errorReporter.typeError(_variable.location(), "Uninitialized \"constant\" variable."); else if (!_variable.value()->annotation().isPure) - { - if (_variable.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050)) - m_errorReporter.typeError( - _variable.value()->location(), - "Initial value for constant variable has to be compile-time constant." - ); - else - m_errorReporter.warning( - _variable.value()->location(), - "Initial value for constant variable has to be compile-time constant. " - "This will fail to compile with the next breaking version change." - ); - } + m_errorReporter.typeError( + _variable.value()->location(), + "Initial value for constant variable has to be compile-time constant." + ); } if (!_variable.isStateVariable()) { @@ -1091,10 +1070,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) if (varDecl.referenceLocation() == VariableDeclaration::Location::Default) errorText += " Did you mean '<type> memory " + varDecl.name() + "'?"; solAssert(m_scope, ""); - if (v050) - m_errorReporter.declarationError(varDecl.location(), errorText); - else - m_errorReporter.warning(varDecl.location(), errorText); + m_errorReporter.declarationError(varDecl.location(), errorText); } } else if (dynamic_cast<MappingType const*>(type(varDecl).get())) @@ -1355,7 +1331,6 @@ bool TypeChecker::visit(Conditional const& _conditional) bool TypeChecker::visit(Assignment const& _assignment) { - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); requireLValue(_assignment.leftHandSide()); TypePointer t = type(_assignment.leftHandSide()); _assignment.annotation().type = t; @@ -1372,25 +1347,8 @@ bool TypeChecker::visit(Assignment const& _assignment) expectType(_assignment.rightHandSide(), *tupleType); // expectType does not cause fatal errors, so we have to check again here. - if (TupleType const* rhsType = dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get())) - { + if (dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get())) checkDoubleStorageAssignment(_assignment); - // @todo For 0.5.0, this code shoud move to TupleType::isImplicitlyConvertibleTo, - // but we cannot do it right now. - if (rhsType->components().size() != tupleType->components().size()) - { - string message = - "Different number of components on the left hand side (" + - toString(tupleType->components().size()) + - ") than on the right hand side (" + - toString(rhsType->components().size()) + - ")."; - if (v050) - m_errorReporter.typeError(_assignment.location(), message); - else - m_errorReporter.warning(_assignment.location(), message); - } - } } else if (t->category() == Type::Category::Mapping) { @@ -1447,14 +1405,12 @@ bool TypeChecker::visit(TupleExpression const& _tuple) } else { - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); bool isPure = true; TypePointer inlineArrayType; for (size_t i = 0; i < components.size(); ++i) { - // Outside of an lvalue-context, the only situation where a component can be empty is (x,). - if (!components[i] && !(i == 1 && components.size() == 2)) + if (!components[i]) m_errorReporter.fatalTypeError(_tuple.location(), "Tuple component cannot be empty."); else if (components[i]) { @@ -1466,10 +1422,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple) { if (_tuple.isInlineArray()) m_errorReporter.fatalTypeError(components[i]->location(), "Array component cannot be empty."); - if (v050) - m_errorReporter.fatalTypeError(components[i]->location(), "Tuple component cannot be empty."); - else - m_errorReporter.warning(components[i]->location(), "Tuple component cannot be empty."); + m_errorReporter.typeError(components[i]->location(), "Tuple component cannot be empty."); } // Note: code generation will visit each of the expression even if they are not assigned from. @@ -1507,11 +1460,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple) if (components.size() == 1) _tuple.annotation().type = type(*components[0]); else - { - if (components.size() == 2 && !components[1]) - types.pop_back(); _tuple.annotation().type = make_shared<TupleType>(types); - } } } @@ -1856,7 +1805,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) if (functionType->takesArbitraryParameters()) m_errorReporter.typeError( _functionCall.location(), - "Named arguments cannnot be used for functions that take arbitrary parameters." + "Named arguments cannot be used for functions that take arbitrary parameters." ); else if (parameterNames.size() > argumentNames.size()) m_errorReporter.typeError(_functionCall.location(), "Some argument names are missing."); @@ -2275,11 +2224,9 @@ void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr) void TypeChecker::endVisit(Literal const& _literal) { - bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050); - if (_literal.looksLikeAddress()) { - // Assign type here if it even looks like an address. This prevents double error in 050 mode for invalid address + // Assign type here if it even looks like an address. This prevents double errors for invalid addresses _literal.annotation().type = make_shared<IntegerType>(160, IntegerType::Modifier::Address); string msg; @@ -2306,20 +2253,11 @@ void TypeChecker::endVisit(Literal const& _literal) } if (_literal.isHexNumber() && _literal.subDenomination() != Literal::SubDenomination::None) - { - if (v050) - m_errorReporter.fatalTypeError( - _literal.location(), - "Hexadecimal numbers cannot be used with unit denominations. " - "You can use an expression of the form \"0x1234 * 1 day\" instead." - ); - else - m_errorReporter.warning( - _literal.location(), - "Hexadecimal numbers with unit denominations are deprecated. " - "You can use an expression of the form \"0x1234 * 1 day\" instead." - ); - } + m_errorReporter.fatalTypeError( + _literal.location(), + "Hexadecimal numbers cannot be used with unit denominations. " + "You can use an expression of the form \"0x1234 * 1 day\" instead." + ); if (_literal.subDenomination() == Literal::SubDenomination::Year) m_errorReporter.typeError( diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index 2245abd6..8dc6b376 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -68,7 +68,7 @@ private: void checkContractDuplicateFunctions(ContractDefinition const& _contract); void checkContractDuplicateEvents(ContractDefinition const& _contract); void checkContractIllegalOverrides(ContractDefinition const& _contract); - /// Reports a type error with an appropiate message if overriden function signature differs. + /// Reports a type error with an appropriate message if overridden function signature differs. /// Also stores the direct super function in the AST annotations. void checkFunctionOverride(FunctionDefinition const& function, FunctionDefinition const& super); void overrideError(FunctionDefinition const& function, FunctionDefinition const& super, std::string message); diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 107eb3aa..18c642c3 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -116,31 +116,22 @@ private: bool ViewPureChecker::check() { - // The bool means "enforce view with errors". - vector<pair<ContractDefinition const*, bool>> contracts; + vector<ContractDefinition const*> contracts; for (auto const& node: m_ast) { SourceUnit const* source = dynamic_cast<SourceUnit const*>(node.get()); solAssert(source, ""); - bool enforceView = source->annotation().experimentalFeatures.count(ExperimentalFeature::V050); - for (ContractDefinition const* c: source->filteredNodes<ContractDefinition>(source->nodes())) - contracts.emplace_back(c, enforceView); + contracts += source->filteredNodes<ContractDefinition>(source->nodes()); } // Check modifiers first to infer their state mutability. for (auto const& contract: contracts) - { - m_enforceViewWithError = contract.second; - for (ModifierDefinition const* mod: contract.first->functionModifiers()) + for (ModifierDefinition const* mod: contract->functionModifiers()) mod->accept(*this); - } for (auto const& contract: contracts) - { - m_enforceViewWithError = contract.second; - contract.first->accept(*this); - } + contract->accept(*this); return !m_errors; } @@ -232,17 +223,20 @@ void ViewPureChecker::reportMutability(StateMutability _mutability, SourceLocati { if (m_currentFunction && m_currentFunction->stateMutability() < _mutability) { - string text; if (_mutability == StateMutability::View) - text = + m_errorReporter.typeError( + _location, "Function declared as pure, but this expression (potentially) reads from the " - "environment or state and thus requires \"view\"."; + "environment or state and thus requires \"view\"." + ); else if (_mutability == StateMutability::NonPayable) - text = + m_errorReporter.typeError( + _location, "Function declared as " + stateMutabilityToString(m_currentFunction->stateMutability()) + ", but this expression (potentially) modifies the state and thus " - "requires non-payable (the default) or payable."; + "requires non-payable (the default) or payable." + ); else solAssert(false, ""); @@ -251,13 +245,7 @@ void ViewPureChecker::reportMutability(StateMutability _mutability, SourceLocati m_currentFunction->stateMutability() == StateMutability::Pure, "" ); - if (!m_enforceViewWithError && m_currentFunction->stateMutability() == StateMutability::View) - m_errorReporter.warning(_location, text); - else - { - m_errors = true; - m_errorReporter.typeError(_location, text); - } + m_errors = true; } if (_mutability > m_currentBestMutability) m_currentBestMutability = _mutability; diff --git a/libsolidity/analysis/ViewPureChecker.h b/libsolidity/analysis/ViewPureChecker.h index 0b882cd8..3db52e7e 100644 --- a/libsolidity/analysis/ViewPureChecker.h +++ b/libsolidity/analysis/ViewPureChecker.h @@ -71,7 +71,6 @@ private: ErrorReporter& m_errorReporter; bool m_errors = false; - bool m_enforceViewWithError = false; StateMutability m_currentBestMutability = StateMutability::Payable; FunctionDefinition const* m_currentFunction = nullptr; std::map<ModifierDefinition const*, StateMutability> m_inferredMutability; |