From 8f68c043583247e56ff848d5193d01e49d4c2e9b Mon Sep 17 00:00:00 2001 From: a3d4 Date: Wed, 6 May 2020 00:38:28 +0200 Subject: [PATCH] Add unique IDs to error reporting calls --- liblangutil/ParserBase.cpp | 6 +- libsolidity/analysis/ConstantEvaluator.cpp | 3 +- libsolidity/analysis/ContractLevelChecker.cpp | 21 +- libsolidity/analysis/ControlFlowAnalyzer.cpp | 3 +- .../analysis/DeclarationTypeChecker.cpp | 12 +- libsolidity/analysis/DocStringAnalyser.cpp | 2 +- libsolidity/analysis/ImmutableValidator.cpp | 7 + libsolidity/analysis/NameAndTypeResolver.cpp | 13 +- libsolidity/analysis/OverrideChecker.cpp | 13 +- libsolidity/analysis/PostTypeChecker.cpp | 8 +- libsolidity/analysis/ReferencesResolver.cpp | 6 +- libsolidity/analysis/StaticAnalyzer.cpp | 13 +- libsolidity/analysis/SyntaxChecker.cpp | 56 +-- libsolidity/analysis/TypeChecker.cpp | 330 +++++++++++------- libsolidity/analysis/ViewPureChecker.cpp | 5 + libsolidity/formal/BMC.cpp | 21 +- libsolidity/formal/CHC.cpp | 4 +- libsolidity/formal/SMTEncoder.cpp | 29 +- libsolidity/interface/CompilerStack.cpp | 4 +- libsolidity/parsing/DocStringParser.cpp | 2 +- libsolidity/parsing/Parser.cpp | 1 + libyul/AsmAnalysis.cpp | 5 +- libyul/AsmParser.cpp | 9 +- libyul/AsmScopeFiller.cpp | 2 + 24 files changed, 382 insertions(+), 193 deletions(-) diff --git a/liblangutil/ParserBase.cpp b/liblangutil/ParserBase.cpp index 747cb37cf..c3a15794b 100644 --- a/liblangutil/ParserBase.cpp +++ b/liblangutil/ParserBase.cpp @@ -145,12 +145,12 @@ void ParserBase::decreaseRecursionDepth() void ParserBase::parserWarning(string const& _description) { - m_errorReporter.warning(currentLocation(), _description); + m_errorReporter.warning(6635_error, currentLocation(), _description); } void ParserBase::parserError(SourceLocation const& _location, string const& _description) { - m_errorReporter.parserError(_location, _description); + m_errorReporter.parserError(2314_error, _location, _description); } void ParserBase::parserError(string const& _description) @@ -165,5 +165,5 @@ void ParserBase::fatalParserError(string const& _description) void ParserBase::fatalParserError(SourceLocation const& _location, string const& _description) { - m_errorReporter.fatalParserError(_location, _description); + m_errorReporter.fatalParserError(1957_error, _location, _description); } diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp index 7617cc518..4bd8b1389 100644 --- a/libsolidity/analysis/ConstantEvaluator.cpp +++ b/libsolidity/analysis/ConstantEvaluator.cpp @@ -47,6 +47,7 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation) TypePointer commonType = left->binaryOperatorResult(_operation.getOperator(), right); if (!commonType) m_errorReporter.fatalTypeError( + 6020_error, _operation.location(), "Operator " + string(TokenTraits::toString(_operation.getOperator())) + @@ -83,7 +84,7 @@ void ConstantEvaluator::endVisit(Identifier const& _identifier) else if (!m_types->count(value.get())) { if (m_depth > 32) - m_errorReporter.fatalTypeError(_identifier.location(), "Cyclic constant definition (or maximum recursion depth exhausted)."); + m_errorReporter.fatalTypeError(5210_error, _identifier.location(), "Cyclic constant definition (or maximum recursion depth exhausted)."); ConstantEvaluator(m_errorReporter, m_depth + 1, m_types).evaluate(*value); } diff --git a/libsolidity/analysis/ContractLevelChecker.cpp b/libsolidity/analysis/ContractLevelChecker.cpp index 18051f99b..1327e89f3 100644 --- a/libsolidity/analysis/ContractLevelChecker.cpp +++ b/libsolidity/analysis/ContractLevelChecker.cpp @@ -78,6 +78,7 @@ void ContractLevelChecker::checkDuplicateFunctions(ContractDefinition const& _co { if (constructor) m_errorReporter.declarationError( + 7997_error, function->location(), SecondarySourceLocation().append("Another declaration is here:", constructor->location()), "More than one constructor defined." @@ -88,6 +89,7 @@ void ContractLevelChecker::checkDuplicateFunctions(ContractDefinition const& _co { if (fallback) m_errorReporter.declarationError( + 7301_error, function->location(), SecondarySourceLocation().append("Another declaration is here:", fallback->location()), "Only one fallback function is allowed." @@ -98,6 +100,7 @@ void ContractLevelChecker::checkDuplicateFunctions(ContractDefinition const& _co { if (receive) m_errorReporter.declarationError( + 4046_error, function->location(), SecondarySourceLocation().append("Another declaration is here:", receive->location()), "Only one receive function is allowed." @@ -147,6 +150,7 @@ void ContractLevelChecker::findDuplicateDefinitions(map> const ssl.limitSize(_message); m_errorReporter.declarationError( + 1686_error, overloads[i]->location(), ssl, _message @@ -197,9 +201,9 @@ void ContractLevelChecker::checkAbstractDefinitions(ContractDefinition const& _c if (_contract.abstract()) { if (_contract.contractKind() == ContractKind::Interface) - m_errorReporter.typeError(_contract.location(), "Interfaces do not need the \"abstract\" keyword, they are abstract implicitly."); + m_errorReporter.typeError(9348_error, _contract.location(), "Interfaces do not need the \"abstract\" keyword, they are abstract implicitly."); else if (_contract.contractKind() == ContractKind::Library) - m_errorReporter.typeError(_contract.location(), "Libraries cannot be abstract."); + m_errorReporter.typeError(9571_error, _contract.location(), "Libraries cannot be abstract."); else solAssert(_contract.contractKind() == ContractKind::Contract, ""); } @@ -215,7 +219,8 @@ void ContractLevelChecker::checkAbstractDefinitions(ContractDefinition const& _c SecondarySourceLocation ssl; for (auto declaration: _contract.annotation().unimplementedDeclarations) ssl.append("Missing implementation: ", declaration->location()); - m_errorReporter.typeError(_contract.location(), ssl, + m_errorReporter.typeError( + 3656_error,_contract.location(), ssl, "Contract \"" + _contract.annotation().canonicalName + "\" should be marked as abstract."); @@ -243,6 +248,7 @@ void ContractLevelChecker::checkBaseConstructorArguments(ContractDefinition cons } else m_errorReporter.declarationError( + 1563_error, modifier->location(), "Modifier-style base constructor call without arguments." ); @@ -304,6 +310,7 @@ void ContractLevelChecker::annotateBaseConstructorArguments( } m_errorReporter.declarationError( + 3364_error, *mainLocation, ssl, "Base constructor arguments given twice." @@ -343,6 +350,7 @@ void ContractLevelChecker::checkExternalTypeClashes(ContractDefinition const& _c for (size_t j = i + 1; j < it.second.size(); ++j) if (!it.second[i].second->hasEqualParameterTypes(*it.second[j].second)) m_errorReporter.typeError( + 9914_error, it.second[j].first->location(), "Function overload clash during conversion to external types for arguments." ); @@ -356,6 +364,7 @@ void ContractLevelChecker::checkHashCollisions(ContractDefinition const& _contra util::FixedHash<4> const& hash = it.first; if (hashes.count(hash)) m_errorReporter.typeError( + 1860_error, _contract.location(), string("Function signature hash collision for ") + it.second->externalSignature() ); @@ -369,11 +378,11 @@ void ContractLevelChecker::checkLibraryRequirements(ContractDefinition const& _c return; if (!_contract.baseContracts().empty()) - m_errorReporter.typeError(_contract.location(), "Library is not allowed to inherit."); + m_errorReporter.typeError(9469_error, _contract.location(), "Library is not allowed to inherit."); for (auto const& var: _contract.stateVariables()) if (!var->isConstant()) - m_errorReporter.typeError(var->location(), "Library cannot have non-constant state variables"); + m_errorReporter.typeError(9957_error, var->location(), "Library cannot have non-constant state variables"); } void ContractLevelChecker::checkBaseABICompatibility(ContractDefinition const& _contract) @@ -412,6 +421,7 @@ void ContractLevelChecker::checkBaseABICompatibility(ContractDefinition const& _ if (!errors.infos.empty()) m_errorReporter.fatalTypeError( + 6594_error, _contract.location(), errors, std::string("Contract \"") + @@ -428,6 +438,7 @@ void ContractLevelChecker::checkPayableFallbackWithoutReceive(ContractDefinition if (auto const* fallback = _contract.fallbackFunction()) if (fallback->isPayable() && !_contract.interfaceFunctionList().empty() && !_contract.receiveFunction()) m_errorReporter.warning( + 3628_error, _contract.location(), "This contract has a payable fallback function, but no receive ether function. Consider adding a receive ether function.", SecondarySourceLocation{}.append("The payable fallback function is defined here.", fallback->location()) diff --git a/libsolidity/analysis/ControlFlowAnalyzer.cpp b/libsolidity/analysis/ControlFlowAnalyzer.cpp index 1a001eb1e..84979082f 100644 --- a/libsolidity/analysis/ControlFlowAnalyzer.cpp +++ b/libsolidity/analysis/ControlFlowAnalyzer.cpp @@ -136,6 +136,7 @@ void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNod ssl.append("The variable was declared here.", variableOccurrence->declaration().location()); m_errorReporter.typeError( + 3464_error, variableOccurrence->occurrence() ? *variableOccurrence->occurrence() : variableOccurrence->declaration().location(), @@ -176,6 +177,6 @@ void ControlFlowAnalyzer::checkUnreachable(CFGNode const* _entry, CFGNode const* // Extend the location, as long as the next location overlaps (unreachable is sorted). for (; it != unreachable.end() && it->start <= location.end; ++it) location.end = std::max(location.end, it->end); - m_errorReporter.warning(location, "Unreachable code."); + m_errorReporter.warning(5740_error, location, "Unreachable code."); } } diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index 0c53732d6..4e55151e9 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -188,12 +188,14 @@ void DeclarationTypeChecker::endVisit(Mapping const& _mapping) { if (contractType->contractDefinition().isLibrary()) m_errorReporter.fatalTypeError( + 1665_error, typeName->location(), "Library types cannot be used as mapping keys." ); } else if (typeName->annotation().type->category() != Type::Category::Enum) m_errorReporter.fatalTypeError( + 7804_error, typeName->location(), "Only elementary types, contract types or enums are allowed as mapping keys." ); @@ -253,9 +255,9 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) return; if (_variable.isConstant() && !_variable.isStateVariable()) - m_errorReporter.declarationError(_variable.location(), "The \"constant\" keyword can only be used for state variables."); + m_errorReporter.declarationError(1788_error, _variable.location(), "The \"constant\" keyword can only be used for state variables."); if (_variable.immutable() && !_variable.isStateVariable()) - m_errorReporter.declarationError(_variable.location(), "The \"immutable\" keyword can only be used for state variables."); + m_errorReporter.declarationError(8297_error, _variable.location(), "The \"immutable\" keyword can only be used for state variables."); if (!_variable.typeName()) { @@ -360,19 +362,19 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) void DeclarationTypeChecker::typeError(SourceLocation const& _location, string const& _description) { m_errorOccurred = true; - m_errorReporter.typeError(_location, _description); + m_errorReporter.typeError(2311_error, _location, _description); } void DeclarationTypeChecker::fatalTypeError(SourceLocation const& _location, string const& _description) { m_errorOccurred = true; - m_errorReporter.fatalTypeError(_location, _description); + m_errorReporter.fatalTypeError(5651_error, _location, _description); } void DeclarationTypeChecker::fatalDeclarationError(SourceLocation const& _location, string const& _description) { m_errorOccurred = true; - m_errorReporter.fatalDeclarationError(_location, _description); + m_errorReporter.fatalDeclarationError(2046_error, _location, _description); } bool DeclarationTypeChecker::check(ASTNode const& _node) diff --git a/libsolidity/analysis/DocStringAnalyser.cpp b/libsolidity/analysis/DocStringAnalyser.cpp index ee0a39163..53edc8cdf 100644 --- a/libsolidity/analysis/DocStringAnalyser.cpp +++ b/libsolidity/analysis/DocStringAnalyser.cpp @@ -173,5 +173,5 @@ void DocStringAnalyser::parseDocStrings( void DocStringAnalyser::appendError(SourceLocation const& _location, string const& _description) { m_errorOccured = true; - m_errorReporter.docstringParsingError(_location, _description); + m_errorReporter.docstringParsingError(7816_error, _location, _description); } diff --git a/libsolidity/analysis/ImmutableValidator.cpp b/libsolidity/analysis/ImmutableValidator.cpp index a63d38ccf..0fad0a66d 100644 --- a/libsolidity/analysis/ImmutableValidator.cpp +++ b/libsolidity/analysis/ImmutableValidator.cpp @@ -166,33 +166,39 @@ void ImmutableValidator::analyseVariableReference(VariableDeclaration const& _va { if (!m_currentConstructor) m_errorReporter.typeError( + 1581_error, _expression.location(), "Immutable variables can only be initialized inline or assigned directly in the constructor." ); else if (m_currentConstructor->annotation().contract->id() != _variableReference.annotation().contract->id()) m_errorReporter.typeError( + 7484_error, _expression.location(), "Immutable variables must be initialized in the constructor of the contract they are defined in." ); else if (m_inLoop) m_errorReporter.typeError( + 6672_error, _expression.location(), "Immutable variables can only be initialized once, not in a while statement." ); else if (m_inBranch) m_errorReporter.typeError( + 4599_error, _expression.location(), "Immutable variables must be initialized unconditionally, not in an if statement." ); if (!m_initializedStateVariables.emplace(&_variableReference).second) m_errorReporter.typeError( + 1574_error, _expression.location(), "Immutable state variable already initialized." ); } else if (m_inConstructionContext) m_errorReporter.typeError( + 7733_error, _expression.location(), "Immutable variables cannot be read during contract creation time, which means " "they cannot be read in the constructor or any function or modifier called from it." @@ -206,6 +212,7 @@ void ImmutableValidator::checkAllVariablesInitialized(solidity::langutil::Source if (varDecl->immutable()) if (!util::contains(m_initializedStateVariables, varDecl)) m_errorReporter.typeError( + 2658_error, _location, solidity::langutil::SecondarySourceLocation().append("Not initialized: ", varDecl->location()), "Construction control flow ends without initializing all immutable state variables." diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 65831ec86..87482b78c 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -80,6 +80,7 @@ bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, maplocation(), "Import \"" + path + "\" (referenced as \"" + imp->path() + "\") not found." ); @@ -95,6 +96,7 @@ bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, maplocation(), "Declaration \"" + alias.symbol->name() + @@ -208,6 +210,7 @@ void NameAndTypeResolver::warnVariablesNamedLikeInstructions() // Don't warn the user for what the user did not. continue; m_errorReporter.warning( + 8261_error, declaration->location(), "Variable is shadowed in inline assembly by an instruction of the same name" ); @@ -326,6 +329,7 @@ void NameAndTypeResolver::importInheritedScope(ContractDefinition const& _base) } m_errorReporter.declarationError( + 9097_error, secondDeclarationLocation, SecondarySourceLocation().append("The previous declaration is here:", firstDeclarationLocation), "Identifier already declared." @@ -343,19 +347,19 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) UserDefinedTypeName const& baseName = baseSpecifier->name(); auto base = dynamic_cast(baseName.annotation().referencedDeclaration); if (!base) - m_errorReporter.fatalTypeError(baseName.location(), "Contract expected."); + m_errorReporter.fatalTypeError(8758_error, baseName.location(), "Contract expected."); // "push_front" has the effect that bases mentioned later can overwrite members of bases // mentioned earlier input.back().push_front(base); vector const& basesBases = base->annotation().linearizedBaseContracts; if (basesBases.empty()) - m_errorReporter.fatalTypeError(baseName.location(), "Definition of base has to precede definition of derived contract"); + m_errorReporter.fatalTypeError(2449_error, baseName.location(), "Definition of base has to precede definition of derived contract"); input.push_front(list(basesBases.begin(), basesBases.end())); } input.back().push_front(&_contract); vector result = cThreeMerge(input); if (result.empty()) - m_errorReporter.fatalTypeError(_contract.location(), "Linearization of inheritance graph impossible"); + m_errorReporter.fatalTypeError(5005_error, _contract.location(), "Linearization of inheritance graph impossible"); _contract.annotation().linearizedBaseContracts = result; _contract.annotation().contractDependencies.insert(result.begin() + 1, result.end()); } @@ -476,6 +480,7 @@ bool DeclarationRegistrationHelper::registerDeclaration( } _errorReporter.declarationError( + 2333_error, secondDeclarationLocation, SecondarySourceLocation().append("The previous declaration is here:", firstDeclarationLocation), "Identifier already declared." @@ -486,6 +491,7 @@ bool DeclarationRegistrationHelper::registerDeclaration( { if (dynamic_cast(shadowedDeclaration)) _errorReporter.warning( + 2319_error, *_errorLocation, "This declaration shadows a builtin symbol." ); @@ -493,6 +499,7 @@ bool DeclarationRegistrationHelper::registerDeclaration( { auto shadowedLocation = shadowedDeclaration->location(); _errorReporter.warning( + 2519_error, _declaration.location(), "This declaration shadows an existing declaration.", SecondarySourceLocation().append("The shadowed declaration is here:", shadowedLocation) diff --git a/libsolidity/analysis/OverrideChecker.cpp b/libsolidity/analysis/OverrideChecker.cpp index 91b45d33c..fbff807f9 100644 --- a/libsolidity/analysis/OverrideChecker.cpp +++ b/libsolidity/analysis/OverrideChecker.cpp @@ -461,6 +461,7 @@ void OverrideChecker::checkIllegalOverrides(ContractDefinition const& _contract) { if (contains_if(inheritedFuncs, MatchByName{modifier->name()})) m_errorReporter.typeError( + 5631_error, modifier->location(), "Override changes function or public state variable to modifier." ); @@ -474,7 +475,7 @@ void OverrideChecker::checkIllegalOverrides(ContractDefinition const& _contract) continue; if (contains_if(inheritedMods, MatchByName{function->name()})) - m_errorReporter.typeError(function->location(), "Override changes modifier to function."); + m_errorReporter.typeError(1469_error, function->location(), "Override changes modifier to function."); checkOverrideList(OverrideProxy{function}, inheritedFuncs); } @@ -484,7 +485,7 @@ void OverrideChecker::checkIllegalOverrides(ContractDefinition const& _contract) continue; if (contains_if(inheritedMods, MatchByName{stateVar->name()})) - m_errorReporter.typeError(stateVar->location(), "Override changes modifier to public state variable."); + m_errorReporter.typeError(1456_error, stateVar->location(), "Override changes modifier to public state variable."); checkOverrideList(OverrideProxy{stateVar}, inheritedFuncs); } @@ -500,6 +501,7 @@ void OverrideChecker::checkOverride(OverrideProxy const& _overriding, OverridePr if (_overriding.isModifier() && *_overriding.modifierType() != *_super.modifierType()) m_errorReporter.typeError( + 1078_error, _overriding.location(), "Override changes modifier signature." ); @@ -593,6 +595,7 @@ void OverrideChecker::overrideListError( contractSingularPlural = "contracts "; m_errorReporter.typeError( + 5883_error, _item.overrides() ? _item.overrides()->location() : _item.location(), ssl, _message1 + @@ -606,6 +609,7 @@ void OverrideChecker::overrideListError( void OverrideChecker::overrideError(Declaration const& _overriding, Declaration const& _super, string const& _message, string const& _secondaryMsg) { m_errorReporter.typeError( + 9456_error, _overriding.location(), SecondarySourceLocation().append(_secondaryMsg, _super.location()), _message @@ -616,6 +620,7 @@ void OverrideChecker::overrideError(Declaration const& _overriding, Declaration void OverrideChecker::overrideError(OverrideProxy const& _overriding, OverrideProxy const& _super, string const& _message, string const& _secondaryMsg) { m_errorReporter.typeError( + 1452_error, _overriding.location(), SecondarySourceLocation().append(_secondaryMsg, _super.location()), _message @@ -718,7 +723,7 @@ void OverrideChecker::checkAmbiguousOverridesInternal(set _baseCa " Since one of the bases defines a public state variable which cannot be overridden, " "you have to change the inheritance layout or the names of the functions."; - m_errorReporter.typeError(_location, ssl, message); + m_errorReporter.typeError(6480_error, _location, ssl, message); } set OverrideChecker::resolveOverrideList(OverrideSpecifier const& _overrides) const @@ -766,6 +771,7 @@ void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySign SecondarySourceLocation ssl; ssl.append("First occurrence here: ", list[i-1]->location()); m_errorReporter.typeError( + 4520_error, list[i]->location(), ssl, "Duplicate contract \"" + @@ -791,6 +797,7 @@ void OverrideChecker::checkOverrideList(OverrideProxy _item, OverrideProxyBySign if (_item.overrides() && expectedContracts.empty()) m_errorReporter.typeError( + 7792_error, _item.overrides()->location(), _item.astNodeNameCapitalized() + " has override specified but does not override anything." ); diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp index 62317587a..1b5b5b7c3 100644 --- a/libsolidity/analysis/PostTypeChecker.cpp +++ b/libsolidity/analysis/PostTypeChecker.cpp @@ -122,6 +122,7 @@ struct ConstStateVarCircularReferenceChecker: public PostTypeChecker::Checker for (auto declaration: m_constVariables) if (auto identifier = findCycle(*declaration)) m_errorReporter.typeError( + 6161_error, declaration->location(), "The value of the constant " + declaration->name() + " has a cyclic dependency via " + identifier->name() + "." @@ -165,7 +166,7 @@ struct ConstStateVarCircularReferenceChecker: public PostTypeChecker::Checker auto visitor = [&](VariableDeclaration const& _variable, util::CycleDetector& _cycleDetector, size_t _depth) { if (_depth >= 256) - m_errorReporter.fatalDeclarationError(_variable.location(), "Variable definition exhausting cyclic dependency validator."); + m_errorReporter.fatalDeclarationError(7380_error, _variable.location(), "Variable definition exhausting cyclic dependency validator."); // Iterating through the dependencies needs to be deterministic and thus cannot // depend on the memory layout. @@ -209,6 +210,7 @@ struct OverrideSpecifierChecker: public PostTypeChecker::Checker TypeType const* actualTypeType = dynamic_cast(decl->type()); m_errorReporter.typeError( + 9301_error, override->location(), "Expected contract but got " + actualTypeType->actualType()->toString(true) + @@ -243,6 +245,7 @@ struct ModifierContextChecker: public PostTypeChecker::Checker if (ModifierType const* type = dynamic_cast(_identifier.annotation().type)) { m_errorReporter.typeError( + 3112_error, _identifier.location(), "Modifier can only be referenced in function headers." ); @@ -280,6 +283,7 @@ struct EventOutsideEmitChecker: public PostTypeChecker::Checker // Check for event outside of emit statement if (!m_insideEmitStatement && functionType->kind() == FunctionType::Kind::Event) m_errorReporter.typeError( + 3132_error, _functionCall.location(), "Event invocations have to be prefixed by \"emit\"." ); @@ -308,7 +312,7 @@ struct NoVariablesInInterfaceChecker: public PostTypeChecker::Checker && !_variable.isCallableOrCatchParameter() && !m_insideStruct ) - m_errorReporter.typeError(_variable.location(), "Variables cannot be declared in interfaces."); + m_errorReporter.typeError(8274_error, _variable.location(), "Variables cannot be declared in interfaces."); return true; } diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index f72253c1f..3415dee22 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -268,19 +268,19 @@ void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl) void ReferencesResolver::declarationError(SourceLocation const& _location, string const& _description) { m_errorOccurred = true; - m_errorReporter.declarationError(_location, _description); + m_errorReporter.declarationError(8532_error, _location, _description); } void ReferencesResolver::declarationError(SourceLocation const& _location, SecondarySourceLocation const& _ssl, string const& _description) { m_errorOccurred = true; - m_errorReporter.declarationError(_location, _ssl, _description); + m_errorReporter.declarationError(3881_error, _location, _ssl, _description); } void ReferencesResolver::fatalDeclarationError(SourceLocation const& _location, string const& _description) { m_errorOccurred = true; - m_errorReporter.fatalDeclarationError(_location, _description); + m_errorReporter.fatalDeclarationError(6546_error, _location, _description); } } diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index c53bc03fa..3cbfa4db4 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -120,13 +120,14 @@ void StaticAnalyzer::endVisit(FunctionDefinition const&) { if (var.first.second->isCallableOrCatchParameter()) m_errorReporter.warning( + 5667_error, var.first.second->location(), "Unused " + string(var.first.second->isTryCatchParameter() ? "try/catch" : "function") + " parameter. Remove or comment out the variable name to silence this warning." ); else - m_errorReporter.warning(var.first.second->location(), "Unused local variable."); + m_errorReporter.warning(2072_error, var.first.second->location(), "Unused local variable."); } m_localVarUseCount.clear(); m_constructor = false; @@ -159,6 +160,7 @@ bool StaticAnalyzer::visit(VariableDeclaration const& _variable) set structsSeen; if (structureSizeEstimate(*_variable.type(), structsSeen) >= bigint(1) << 64) m_errorReporter.warning( + 3408_error, _variable.location(), "Variable covers a large part of storage and thus makes collisions likely. " "Either use mappings or dynamic arrays and allow their size to be increased only " @@ -183,6 +185,7 @@ bool StaticAnalyzer::visit(ExpressionStatement const& _statement) { if (_statement.expression().annotation().isPure) m_errorReporter.warning( + 6133_error, _statement.location(), "Statement has no effect." ); @@ -196,11 +199,13 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) { if (type->kind() == MagicType::Kind::Message && _memberAccess.memberName() == "gas") m_errorReporter.typeError( + 1400_error, _memberAccess.location(), "\"msg.gas\" has been deprecated in favor of \"gasleft()\"" ); else if (type->kind() == MagicType::Kind::Block && _memberAccess.memberName() == "blockhash") m_errorReporter.typeError( + 8113_error, _memberAccess.location(), "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"" ); @@ -211,6 +216,7 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) ContractType const& contract = dynamic_cast(*type->typeArgument()); if (m_constructorUsesAssembly->check(contract.contractDefinition())) m_errorReporter.warning( + 6417_error, _memberAccess.location(), "The constructor of the contract (or its base) uses inline assembly. " "Because of that, it might be that the deployed bytecode is different from type(...).runtimeCode." @@ -222,6 +228,7 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) if (auto const* type = dynamic_cast(_memberAccess.annotation().type)) if (type->kind() == FunctionType::Kind::BareCallCode) m_errorReporter.typeError( + 2256_error, _memberAccess.location(), "\"callcode\" has been deprecated in favour of \"delegatecall\"." ); @@ -235,6 +242,7 @@ bool StaticAnalyzer::visit(MemberAccess const& _memberAccess) { if (id->name() == "this") m_errorReporter.warning( + 5805_error, id->location(), "\"this\" used in constructor. " "Note that external functions of a contract " @@ -285,6 +293,7 @@ bool StaticAnalyzer::visit(BinaryOperation const& _operation) )) if (rhs->isZero()) m_errorReporter.typeError( + 1211_error, _operation.location(), (_operation.getOperator() == Token::Div) ? "Division by zero." : "Modulo zero." ); @@ -307,6 +316,7 @@ bool StaticAnalyzer::visit(FunctionCall const& _functionCall) )) if (lastArg->isZero()) m_errorReporter.typeError( + 4195_error, _functionCall.location(), "Arithmetic modulo zero." ); @@ -317,6 +327,7 @@ bool StaticAnalyzer::visit(FunctionCall const& _functionCall) functionType->declaration().scope() == m_currentContract ) m_errorReporter.typeError( + 6700_error, _functionCall.location(), SecondarySourceLocation().append( "The function declaration is here:", diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index bd2060d6a..c3267c37f 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -69,7 +69,7 @@ void SyntaxChecker::endVisit(SourceUnit const& _sourceUnit) string(";\""); // when reporting the warning, print the source name only - m_errorReporter.warning({-1, -1, _sourceUnit.location().source}, errorString); + m_errorReporter.warning(3420_error, {-1, -1, _sourceUnit.location().source}, errorString); } m_sourceUnit = nullptr; } @@ -79,18 +79,20 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma) solAssert(!_pragma.tokens().empty(), ""); solAssert(_pragma.tokens().size() == _pragma.literals().size(), ""); if (_pragma.tokens()[0] != Token::Identifier) - m_errorReporter.syntaxError(_pragma.location(), "Invalid pragma \"" + _pragma.literals()[0] + "\""); + m_errorReporter.syntaxError(5226_error, _pragma.location(), "Invalid pragma \"" + _pragma.literals()[0] + "\""); else if (_pragma.literals()[0] == "experimental") { solAssert(m_sourceUnit, ""); vector literals(_pragma.literals().begin() + 1, _pragma.literals().end()); if (literals.empty()) m_errorReporter.syntaxError( + 9679_error, _pragma.location(), "Experimental feature name is missing." ); else if (literals.size() > 1) m_errorReporter.syntaxError( + 6022_error, _pragma.location(), "Stray arguments." ); @@ -98,17 +100,17 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma) { string const literal = literals[0]; if (literal.empty()) - m_errorReporter.syntaxError(_pragma.location(), "Empty experimental feature name is invalid."); + m_errorReporter.syntaxError(3250_error, _pragma.location(), "Empty experimental feature name is invalid."); else if (!ExperimentalFeatureNames.count(literal)) - m_errorReporter.syntaxError(_pragma.location(), "Unsupported experimental feature name."); + m_errorReporter.syntaxError(8491_error, _pragma.location(), "Unsupported experimental feature name."); else if (m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeatureNames.at(literal))) - m_errorReporter.syntaxError(_pragma.location(), "Duplicate experimental feature name."); + m_errorReporter.syntaxError(1231_error, _pragma.location(), "Duplicate experimental feature name."); else { auto feature = ExperimentalFeatureNames.at(literal); m_sourceUnit->annotation().experimentalFeatures.insert(feature); if (!ExperimentalFeatureWithoutWarning.count(feature)) - m_errorReporter.warning(_pragma.location(), "Experimental features are turned on. Do not use experimental features on live deployments."); + m_errorReporter.warning(2264_error, _pragma.location(), "Experimental features are turned on. Do not use experimental features on live deployments."); } } } @@ -121,6 +123,7 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma) static SemVerVersion const currentVersion{string(VersionString)}; if (!matchExpression.matches(currentVersion)) m_errorReporter.syntaxError( + 3997_error, _pragma.location(), "Source file requires different compiler version (current compiler is " + string(VersionString) + ") - note that nightly builds are considered to be " @@ -129,7 +132,7 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma) m_versionPragmaFound = true; } else - m_errorReporter.syntaxError(_pragma.location(), "Unknown pragma \"" + _pragma.literals()[0] + "\""); + m_errorReporter.syntaxError(4936_error, _pragma.location(), "Unknown pragma \"" + _pragma.literals()[0] + "\""); return true; } @@ -142,7 +145,7 @@ bool SyntaxChecker::visit(ModifierDefinition const&) void SyntaxChecker::endVisit(ModifierDefinition const& _modifier) { if (_modifier.isImplemented() && !m_placeholderFound) - m_errorReporter.syntaxError(_modifier.body().location(), "Modifier body does not contain '_'."); + m_errorReporter.syntaxError(2883_error, _modifier.body().location(), "Modifier body does not contain '_'."); m_placeholderFound = false; } @@ -150,7 +153,7 @@ void SyntaxChecker::checkSingleStatementVariableDeclaration(ASTNode const& _stat { auto varDecl = dynamic_cast(&_statement); if (varDecl) - m_errorReporter.syntaxError(_statement.location(), "Variable declarations can only be used inside blocks."); + m_errorReporter.syntaxError(9079_error, _statement.location(), "Variable declarations can only be used inside blocks."); } bool SyntaxChecker::visit(IfStatement const& _ifStatement) @@ -189,7 +192,7 @@ bool SyntaxChecker::visit(Continue const& _continueStatement) { if (m_inLoopDepth <= 0) // we're not in a for/while loop, report syntax error - m_errorReporter.syntaxError(_continueStatement.location(), "\"continue\" has to be in a \"for\" or \"while\" loop."); + m_errorReporter.syntaxError(4123_error, _continueStatement.location(), "\"continue\" has to be in a \"for\" or \"while\" loop."); return true; } @@ -197,13 +200,14 @@ bool SyntaxChecker::visit(Break const& _breakStatement) { if (m_inLoopDepth <= 0) // we're not in a for/while loop, report syntax error - m_errorReporter.syntaxError(_breakStatement.location(), "\"break\" has to be in a \"for\" or \"while\" loop."); + m_errorReporter.syntaxError(6102_error, _breakStatement.location(), "\"break\" has to be in a \"for\" or \"while\" loop."); return true; } bool SyntaxChecker::visit(Throw const& _throwStatement) { m_errorReporter.syntaxError( + 4538_error, _throwStatement.location(), "\"throw\" is deprecated in favour of \"revert()\", \"require()\" and \"assert()\"." ); @@ -222,29 +226,29 @@ bool SyntaxChecker::visit(Literal const& _literal) // Generic checks no matter what base this number literal is of: if (value.back() == '_') { - m_errorReporter.syntaxError(_literal.location(), "Invalid use of underscores in number literal. No trailing underscores allowed."); + m_errorReporter.syntaxError(2090_error, _literal.location(), "Invalid use of underscores in number literal. No trailing underscores allowed."); return true; } if (value.find("__") != ASTString::npos) { - m_errorReporter.syntaxError(_literal.location(), "Invalid use of underscores in number literal. Only one consecutive underscores between digits allowed."); + m_errorReporter.syntaxError(2990_error, _literal.location(), "Invalid use of underscores in number literal. Only one consecutive underscores between digits allowed."); return true; } if (!_literal.isHexNumber()) // decimal literal { if (value.find("._") != ASTString::npos) - m_errorReporter.syntaxError(_literal.location(), "Invalid use of underscores in number literal. No underscores in front of the fraction part allowed."); + m_errorReporter.syntaxError(3891_error, _literal.location(), "Invalid use of underscores in number literal. No underscores in front of the fraction part allowed."); if (value.find("_.") != ASTString::npos) - m_errorReporter.syntaxError(_literal.location(), "Invalid use of underscores in number literal. No underscores in front of the fraction part allowed."); + m_errorReporter.syntaxError(1023_error, _literal.location(), "Invalid use of underscores in number literal. No underscores in front of the fraction part allowed."); if (value.find("_e") != ASTString::npos) - m_errorReporter.syntaxError(_literal.location(), "Invalid use of underscores in number literal. No underscore at the end of the mantissa allowed."); + m_errorReporter.syntaxError(6415_error, _literal.location(), "Invalid use of underscores in number literal. No underscore at the end of the mantissa allowed."); if (value.find("e_") != ASTString::npos) - m_errorReporter.syntaxError(_literal.location(), "Invalid use of underscores in number literal. No underscore in front of exponent allowed."); + m_errorReporter.syntaxError(6165_error, _literal.location(), "Invalid use of underscores in number literal. No underscore in front of exponent allowed."); } return true; @@ -253,7 +257,7 @@ bool SyntaxChecker::visit(Literal const& _literal) bool SyntaxChecker::visit(UnaryOperation const& _operation) { if (_operation.getOperator() == Token::Add) - m_errorReporter.syntaxError(_operation.location(), "Use of unary + is disallowed."); + m_errorReporter.syntaxError(9636_error, _operation.location(), "Use of unary + is disallowed."); return true; } @@ -265,6 +269,7 @@ bool SyntaxChecker::visit(InlineAssembly const& _inlineAssembly) if (yul::MSizeFinder::containsMSize(_inlineAssembly.dialect(), _inlineAssembly.operations())) m_errorReporter.syntaxError( + 6553_error, _inlineAssembly.location(), "The msize instruction cannot be used when the Yul optimizer is activated because " "it can change its semantics. Either disable the Yul optimizer or do not use the instruction." @@ -285,7 +290,8 @@ bool SyntaxChecker::visit(ContractDefinition const& _contract) ASTString const& contractName = _contract.name(); for (FunctionDefinition const* function: _contract.definedFunctions()) if (function->name() == contractName) - m_errorReporter.syntaxError(function->location(), + m_errorReporter.syntaxError( + 5796_error,function->location(), "Functions are not allowed to have the same name as the contract. " "If you intend this to be a constructor, use \"constructor(...) { ... }\" to define it." ); @@ -298,15 +304,16 @@ bool SyntaxChecker::visit(FunctionDefinition const& _function) { string suggestedVisibility = _function.isFallback() || _function.isReceive() || m_isInterface ? "external" : "public"; m_errorReporter.syntaxError( + 4937_error, _function.location(), "No visibility specified. Did you intend to add \"" + suggestedVisibility + "\"?" ); } if (m_isInterface && !_function.modifiers().empty()) - m_errorReporter.syntaxError(_function.location(), "Functions in interfaces cannot have modifiers."); + m_errorReporter.syntaxError(5842_error, _function.location(), "Functions in interfaces cannot have modifiers."); else if (!_function.isImplemented() && !_function.modifiers().empty()) - m_errorReporter.syntaxError(_function.location(), "Functions without implementation cannot have modifiers."); + m_errorReporter.syntaxError(2668_error, _function.location(), "Functions without implementation cannot have modifiers."); return true; } @@ -315,11 +322,11 @@ bool SyntaxChecker::visit(FunctionTypeName const& _node) { for (auto const& decl: _node.parameterTypeList()->parameters()) if (!decl->name().empty()) - m_errorReporter.warning(decl->location(), "Naming function type parameters is deprecated."); + m_errorReporter.warning(6162_error, decl->location(), "Naming function type parameters is deprecated."); for (auto const& decl: _node.returnParameterTypeList()->parameters()) if (!decl->name().empty()) - m_errorReporter.syntaxError(decl->location(), "Return parameters in function types may not be named."); + m_errorReporter.syntaxError(7304_error, decl->location(), "Return parameters in function types may not be named."); return true; } @@ -329,6 +336,7 @@ bool SyntaxChecker::visit(VariableDeclarationStatement const& _statement) // Report if none of the variable components in the tuple have a name (only possible via deprecated "var") if (boost::algorithm::all_of_equal(_statement.declarations(), nullptr)) m_errorReporter.syntaxError( + 3299_error, _statement.location(), "The use of the \"var\" keyword is disallowed. The declaration part of the statement can be removed, since it is empty." ); @@ -339,7 +347,7 @@ bool SyntaxChecker::visit(VariableDeclarationStatement const& _statement) bool SyntaxChecker::visit(StructDefinition const& _struct) { if (_struct.members().empty()) - m_errorReporter.syntaxError(_struct.location(), "Defining empty structs is disallowed."); + m_errorReporter.syntaxError(5306_error, _struct.location(), "Defining empty structs is disallowed."); return true; } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index b4030c0c4..7277714b8 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -117,6 +117,7 @@ void TypeChecker::checkDoubleStorageAssignment(Assignment const& _assignment) } if (storageToStorageCopies >= 1 && toStorageCopies >= 2) m_errorReporter.warning( + 7238_error, _assignment.location(), "This assignment performs two copies to storage. Since storage copies do not first " "copy to a temporary location, one of them might be overwritten before the second " @@ -130,6 +131,7 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c vector> arguments = _functionCall.arguments(); if (arguments.size() != 2) m_errorReporter.typeError( + 5782_error, _functionCall.location(), "This function takes two arguments, but " + toString(arguments.size()) + @@ -142,6 +144,7 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c !type(*arguments.front())->isImplicitlyConvertibleTo(*TypeProvider::bytesCalldata()) ) m_errorReporter.typeError( + 1956_error, arguments.front()->location(), "The first argument to \"abi.decode\" must be implicitly convertible to " "bytes memory or bytes calldata, but is of type " + @@ -158,6 +161,7 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c if (!tupleExpression) { m_errorReporter.typeError( + 6444_error, arguments[1]->location(), "The second argument to \"abi.decode\" has to be a tuple of types." ); @@ -186,6 +190,7 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c ); if (!actualType->fullEncodingType(false, _abiEncoderV2, false)) m_errorReporter.typeError( + 9611_error, typeArgument->location(), "Decoding type " + actualType->toString(false) + " not supported." ); @@ -193,7 +198,7 @@ TypePointers TypeChecker::typeCheckABIDecodeAndRetrieveReturnType(FunctionCall c } else { - m_errorReporter.typeError(typeArgument->location(), "Argument has to be a type name."); + m_errorReporter.typeError(1039_error, typeArgument->location(), "Argument has to be a type name."); components.push_back(TypeProvider::emptyTuple()); } } @@ -206,6 +211,7 @@ TypePointers TypeChecker::typeCheckMetaTypeFunctionAndRetrieveReturnType(Functio if (arguments.size() != 1) { m_errorReporter.typeError( + 8885_error, _functionCall.location(), "This function takes one argument, but " + toString(arguments.size()) + @@ -220,6 +226,7 @@ TypePointers TypeChecker::typeCheckMetaTypeFunctionAndRetrieveReturnType(Functio ) { m_errorReporter.typeError( + 4259_error, arguments.front()->location(), "Invalid type for argument in function call. " "Contract type required, but " + @@ -238,10 +245,10 @@ void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance) solAssert(base, "Base contract not available."); if (m_scope->isInterface() && !base->isInterface()) - m_errorReporter.typeError(_inheritance.location(), "Interfaces can only inherit from other interfaces."); + m_errorReporter.typeError(6536_error, _inheritance.location(), "Interfaces can only inherit from other interfaces."); if (base->isLibrary()) - m_errorReporter.typeError(_inheritance.location(), "Libraries cannot be inherited from."); + m_errorReporter.typeError(2571_error, _inheritance.location(), "Libraries cannot be inherited from."); auto const& arguments = _inheritance.arguments(); TypePointers parameterTypes; @@ -254,6 +261,7 @@ void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance) if (parameterTypes.size() != arguments->size()) { m_errorReporter.typeError( + 7927_error, _inheritance.location(), "Wrong argument count for constructor call: " + toString(arguments->size()) + @@ -267,6 +275,7 @@ void TypeChecker::endVisit(InheritanceSpecifier const& _inheritance) BoolResult result = type(*(*arguments)[i])->isImplicitlyConvertibleTo(*parameterTypes[i]); if (!result) m_errorReporter.typeErrorConcatenateDescriptions( + 9827_error, (*arguments)[i]->location(), "Invalid type for argument in constructor call. " "Invalid implicit conversion from " + @@ -286,13 +295,13 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor) _usingFor.libraryName().annotation().referencedDeclaration ); if (!library || !library->isLibrary()) - m_errorReporter.fatalTypeError(_usingFor.libraryName().location(), "Library name expected."); + m_errorReporter.fatalTypeError(4357_error, _usingFor.libraryName().location(), "Library name expected."); } void TypeChecker::endVisit(ModifierDefinition const& _modifier) { if (!_modifier.isImplemented() && !_modifier.virtualSemantics()) - m_errorReporter.typeError(_modifier.location(), "Modifiers without implementation must be marked virtual."); + m_errorReporter.typeError(8063_error, _modifier.location(), "Modifiers without implementation must be marked virtual."); } bool TypeChecker::visit(FunctionDefinition const& _function) @@ -302,17 +311,17 @@ bool TypeChecker::visit(FunctionDefinition const& _function) if (_function.markedVirtual()) { if (_function.annotation().contract->isInterface()) - m_errorReporter.warning(_function.location(), "Interface functions are implicitly \"virtual\""); + m_errorReporter.warning(5815_error, _function.location(), "Interface functions are implicitly \"virtual\""); if (_function.visibility() == Visibility::Private) - m_errorReporter.typeError(_function.location(), "\"virtual\" and \"private\" cannot be used together."); + m_errorReporter.typeError(3942_error, _function.location(), "\"virtual\" and \"private\" cannot be used together."); } if (_function.isPayable()) { if (isLibraryFunction) - m_errorReporter.typeError(_function.location(), "Library functions cannot be payable."); + m_errorReporter.typeError(7708_error, _function.location(), "Library functions cannot be payable."); if (_function.isOrdinary() && !_function.isPartOfExternalInterface()) - m_errorReporter.typeError(_function.location(), "Internal functions cannot be payable."); + m_errorReporter.typeError(5587_error, _function.location(), "Internal functions cannot be payable."); } auto checkArgumentAndReturnParameter = [&](VariableDeclaration const& var) { if (type(var)->category() == Type::Category::Mapping) @@ -320,9 +329,9 @@ bool TypeChecker::visit(FunctionDefinition const& _function) if (var.referenceLocation() != VariableDeclaration::Location::Storage) { if (!isLibraryFunction && _function.isPublic()) - m_errorReporter.typeError(var.location(), "Mapping types can only have a data location of \"storage\" and thus only be parameters or return variables for internal or library functions."); + m_errorReporter.typeError(3442_error, var.location(), "Mapping types can only have a data location of \"storage\" and thus only be parameters or return variables for internal or library functions."); else - m_errorReporter.typeError(var.location(), "Mapping types can only have a data location of \"storage\"." ); + m_errorReporter.typeError(5380_error, var.location(), "Mapping types can only have a data location of \"storage\"." ); } else { @@ -332,7 +341,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) else { if (!type(var)->canLiveOutsideStorage() && _function.isPublic()) - m_errorReporter.typeError(var.location(), "Type is required to live outside storage."); + m_errorReporter.typeError(3312_error, var.location(), "Type is required to live outside storage."); if (_function.isPublic()) { auto iType = type(var)->interfaceType(isLibraryFunction); @@ -340,7 +349,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) if (!iType) { solAssert(!iType.message().empty(), "Expected detailed error message!"); - m_errorReporter.fatalTypeError(var.location(), iType.message()); + m_errorReporter.fatalTypeError(4103_error, var.location(), iType.message()); } } } @@ -350,6 +359,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) !typeSupportedByOldABIEncoder(*type(var), isLibraryFunction) ) m_errorReporter.typeError( + 4957_error, var.location(), "This type is only supported in ABIEncoderV2. " "Use \"pragma experimental ABIEncoderV2;\" to enable the feature." @@ -380,7 +390,7 @@ bool TypeChecker::visit(FunctionDefinition const& _function) if (modifiers.count(decl)) { if (dynamic_cast(decl)) - m_errorReporter.declarationError(modifier->location(), "Base constructor already provided."); + m_errorReporter.declarationError(1697_error, modifier->location(), "Base constructor already provided."); } else modifiers.insert(decl); @@ -388,25 +398,25 @@ bool TypeChecker::visit(FunctionDefinition const& _function) if (m_scope->isInterface()) { if (_function.isImplemented()) - m_errorReporter.typeError(_function.location(), "Functions in interfaces cannot have an implementation."); + m_errorReporter.typeError(4726_error, _function.location(), "Functions in interfaces cannot have an implementation."); if (_function.visibility() != Visibility::External) - m_errorReporter.typeError(_function.location(), "Functions in interfaces must be declared external."); + m_errorReporter.typeError(1560_error, _function.location(), "Functions in interfaces must be declared external."); if (_function.isConstructor()) - m_errorReporter.typeError(_function.location(), "Constructor cannot be defined in interfaces."); + m_errorReporter.typeError(6482_error, _function.location(), "Constructor cannot be defined in interfaces."); } else if (m_scope->contractKind() == ContractKind::Library) if (_function.isConstructor()) - m_errorReporter.typeError(_function.location(), "Constructor cannot be defined in libraries."); + m_errorReporter.typeError(7634_error, _function.location(), "Constructor cannot be defined in libraries."); if (_function.isImplemented()) _function.body().accept(*this); else if (_function.isConstructor()) - m_errorReporter.typeError(_function.location(), "Constructor must be implemented if declared."); + m_errorReporter.typeError(5700_error, _function.location(), "Constructor must be implemented if declared."); else if (isLibraryFunction) - m_errorReporter.typeError(_function.location(), "Library functions must be implemented if declared."); + m_errorReporter.typeError(9231_error, _function.location(), "Library functions must be implemented if declared."); else if (!_function.virtualSemantics()) - m_errorReporter.typeError(_function.location(), "Functions without implementation must be marked virtual."); + m_errorReporter.typeError(5424_error, _function.location(), "Functions without implementation must be marked virtual."); if (_function.isFallback()) @@ -431,7 +441,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) if (auto contractType = dynamic_cast(varType)) if (contractType->contractDefinition().isLibrary()) - m_errorReporter.typeError(_variable.location(), "The type of a variable cannot be a library."); + m_errorReporter.typeError(1273_error, _variable.location(), "The type of a variable cannot be a library."); if (_variable.value()) expectType(*_variable.value(), *varType); if (_variable.isConstant()) @@ -442,13 +452,14 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) if (auto arrayType = dynamic_cast(_variable.type())) allowed = arrayType->isByteArray(); if (!allowed) - m_errorReporter.typeError(_variable.location(), "Constants of non-value type not yet implemented."); + m_errorReporter.typeError(9259_error, _variable.location(), "Constants of non-value type not yet implemented."); } if (!_variable.value()) - m_errorReporter.typeError(_variable.location(), "Uninitialized \"constant\" variable."); + m_errorReporter.typeError(4266_error, _variable.location(), "Uninitialized \"constant\" variable."); else if (!_variable.value()->annotation().isPure) m_errorReporter.typeError( + 8349_error, _variable.value()->location(), "Initial value for constant variable has to be compile-time constant." ); @@ -456,12 +467,12 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) else if (_variable.immutable()) { if (!_variable.type()->isValueType()) - m_errorReporter.typeError(_variable.location(), "Immutable variables cannot have a non-value type."); + m_errorReporter.typeError(6377_error, _variable.location(), "Immutable variables cannot have a non-value type."); if ( auto const* functionType = dynamic_cast(_variable.type()); functionType && functionType->kind() == FunctionType::Kind::External ) - m_errorReporter.typeError(_variable.location(), "Immutable variables of external function type are not yet supported."); + m_errorReporter.typeError(3366_error, _variable.location(), "Immutable variables of external function type are not yet supported."); solAssert(_variable.type()->sizeOnStack() == 1 || m_errorReporter.hasErrors(), ""); } @@ -469,7 +480,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) { if (varType->dataStoredIn(DataLocation::Memory) || varType->dataStoredIn(DataLocation::CallData)) if (!varType->canLiveOutsideStorage()) - m_errorReporter.typeError(_variable.location(), "Type " + varType->toString() + " is only valid in storage."); + m_errorReporter.typeError(4061_error, _variable.location(), "Type " + varType->toString() + " is only valid in storage."); } else if (_variable.visibility() >= Visibility::Public) { @@ -481,14 +492,15 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) if (!typeSupportedByOldABIEncoder(*param, false /* isLibrary */)) unsupportedTypes.emplace_back(param->toString()); if (!unsupportedTypes.empty()) - m_errorReporter.typeError(_variable.location(), + m_errorReporter.typeError( + 2763_error,_variable.location(), "The following types are only supported for getters in ABIEncoderV2: " + joinHumanReadable(unsupportedTypes) + ". Either remove \"public\" or use \"pragma experimental ABIEncoderV2;\" to enable the feature." ); } if (!getter.interfaceFunctionType()) - m_errorReporter.typeError(_variable.location(), "Internal or recursive type is not allowed for public state variables."); + m_errorReporter.typeError(6744_error, _variable.location(), "Internal or recursive type is not allowed for public state variables."); } if (auto referenceType = dynamic_cast(varType)) @@ -499,7 +511,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) if (!result) { solAssert(!result.message().empty(), "Expected detailed error message"); - m_errorReporter.typeError(_variable.location(), result.message()); + m_errorReporter.typeError(1534_error, _variable.location(), result.message()); } } @@ -536,12 +548,13 @@ void TypeChecker::visitManually( } if (!parameters) { - m_errorReporter.typeError(_modifier.location(), "Referenced declaration is neither modifier nor base class."); + m_errorReporter.typeError(4659_error, _modifier.location(), "Referenced declaration is neither modifier nor base class."); return; } if (parameters->size() != arguments.size()) { m_errorReporter.typeError( + 2973_error, _modifier.location(), "Wrong argument count for modifier invocation: " + toString(arguments.size()) + @@ -556,6 +569,7 @@ void TypeChecker::visitManually( BoolResult result = type(*arguments[i])->isImplicitlyConvertibleTo(*type(*(*parameters)[i])); if (!result) m_errorReporter.typeErrorConcatenateDescriptions( + 4649_error, arguments[i]->location(), "Invalid type for argument in modifier invocation. " "Invalid implicit conversion from " + @@ -577,23 +591,24 @@ bool TypeChecker::visit(EventDefinition const& _eventDef) if (var->isIndexed()) numIndexed++; if (!type(*var)->canLiveOutsideStorage()) - m_errorReporter.typeError(var->location(), "Type is required to live outside storage."); + m_errorReporter.typeError(3448_error, var->location(), "Type is required to live outside storage."); if (!type(*var)->interfaceType(false)) - m_errorReporter.typeError(var->location(), "Internal or recursive type is not allowed as event parameter type."); + m_errorReporter.typeError(3417_error, var->location(), "Internal or recursive type is not allowed as event parameter type."); if ( !_eventDef.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2) && !typeSupportedByOldABIEncoder(*type(*var), false /* isLibrary */) ) m_errorReporter.typeError( + 3061_error, var->location(), "This type is only supported in ABIEncoderV2. " "Use \"pragma experimental ABIEncoderV2;\" to enable the feature." ); } if (_eventDef.isAnonymous() && numIndexed > 4) - m_errorReporter.typeError(_eventDef.location(), "More than 4 indexed arguments for anonymous event."); + m_errorReporter.typeError(8598_error, _eventDef.location(), "More than 4 indexed arguments for anonymous event."); else if (!_eventDef.isAnonymous() && numIndexed > 3) - m_errorReporter.typeError(_eventDef.location(), "More than 3 indexed arguments for event."); + m_errorReporter.typeError(7249_error, _eventDef.location(), "More than 3 indexed arguments for event."); return false; } @@ -606,7 +621,7 @@ void TypeChecker::endVisit(FunctionTypeName const& _funType) { solAssert(t->annotation().type, "Type not set for parameter."); if (!t->annotation().type->interfaceType(false).get()) - m_errorReporter.typeError(t->location(), "Internal type cannot be used for external function type."); + m_errorReporter.typeError(2582_error, t->location(), "Internal type cannot be used for external function type."); } solAssert(fun.interfaceType(false), "External function type uses internal types."); } @@ -633,7 +648,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) solAssert(var->type(), "Expected variable type!"); if (var->immutable()) { - m_errorReporter.typeError(_identifier.location, "Assembly access to immutable variables is not supported."); + m_errorReporter.typeError(3773_error, _identifier.location, "Assembly access to immutable variables is not supported."); return size_t(-1); } if (var->isConstant()) @@ -642,7 +657,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) if (var && !var->value()) { - m_errorReporter.typeError(_identifier.location, "Constant has no value."); + m_errorReporter.typeError(3224_error, _identifier.location, "Constant has no value."); return size_t(-1); } else if (!var || !type(*var)->isValueType() || ( @@ -650,17 +665,17 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) type(*var->value())->category() != Type::Category::RationalNumber )) { - m_errorReporter.typeError(_identifier.location, "Only direct number constants and references to such constants are supported by inline assembly."); + 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); } else if (_context == yul::IdentifierContext::LValue) { - m_errorReporter.typeError(_identifier.location, "Constant variables cannot be assigned to."); + m_errorReporter.typeError(6252_error, _identifier.location, "Constant variables cannot be assigned to."); return size_t(-1); } else if (requiresStorage) { - m_errorReporter.typeError(_identifier.location, "The suffixes _offset and _slot can only be used on non-constant storage variables."); + m_errorReporter.typeError(6617_error, _identifier.location, "The suffixes _offset and _slot can only be used on non-constant storage variables."); return size_t(-1); } } @@ -669,19 +684,19 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) { if (!var->isStateVariable() && !var->type()->dataStoredIn(DataLocation::Storage)) { - m_errorReporter.typeError(_identifier.location, "The suffixes _offset and _slot can only be used on storage variables."); + m_errorReporter.typeError(3622_error, _identifier.location, "The suffixes _offset and _slot can only be used on storage variables."); return size_t(-1); } else if (_context == yul::IdentifierContext::LValue) { if (var->isStateVariable()) { - m_errorReporter.typeError(_identifier.location, "State variables cannot be assigned to - you have to use \"sstore()\"."); + m_errorReporter.typeError(4713_error, _identifier.location, "State variables cannot be assigned to - you have to use \"sstore()\"."); return size_t(-1); } else if (ref->second.isOffset) { - m_errorReporter.typeError(_identifier.location, "Only _slot can be assigned to."); + m_errorReporter.typeError(9739_error, _identifier.location, "Only _slot can be assigned to."); return size_t(-1); } else @@ -690,26 +705,26 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) } else if (!var->isConstant() && var->isStateVariable()) { - m_errorReporter.typeError(_identifier.location, "Only local variables are supported. To access storage variables, use the _slot and _offset suffixes."); + m_errorReporter.typeError(1408_error, _identifier.location, "Only local variables are supported. To access storage variables, use the _slot and _offset suffixes."); return size_t(-1); } else if (var->type()->dataStoredIn(DataLocation::Storage)) { - m_errorReporter.typeError(_identifier.location, "You have to use the _slot or _offset suffix to access storage reference variables."); + m_errorReporter.typeError(9068_error, _identifier.location, "You have to use the _slot or _offset suffix to access storage reference variables."); return size_t(-1); } else if (var->type()->sizeOnStack() != 1) { if (var->type()->dataStoredIn(DataLocation::CallData)) - m_errorReporter.typeError(_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."); + 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(_identifier.location, "Only types that use one stack slot are supported."); + m_errorReporter.typeError(9857_error, _identifier.location, "Only types that use one stack slot are supported."); return size_t(-1); } } else if (requiresStorage) { - m_errorReporter.typeError(_identifier.location, "The suffixes _offset and _slot can only be used on storage variables."); + m_errorReporter.typeError(7944_error, _identifier.location, "The suffixes _offset and _slot can only be used on storage variables."); return size_t(-1); } else if (_context == yul::IdentifierContext::LValue) @@ -717,7 +732,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) if (dynamic_cast(declaration)) return size_t(-1); - m_errorReporter.typeError(_identifier.location, "Only local variables can be assigned to in inline assembly."); + m_errorReporter.typeError(1990_error, _identifier.location, "Only local variables can be assigned to in inline assembly."); return size_t(-1); } @@ -726,7 +741,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) solAssert(!!declaration->type(), "Type of declaration required but not yet determined."); if (dynamic_cast(declaration)) { - m_errorReporter.declarationError(_identifier.location, "Access to functions is not allowed in inline assembly."); + m_errorReporter.declarationError(2025_error, _identifier.location, "Access to functions is not allowed in inline assembly."); return size_t(-1); } else if (dynamic_cast(declaration)) @@ -736,7 +751,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) { if (!contract->isLibrary()) { - m_errorReporter.typeError(_identifier.location, "Expected a library."); + m_errorReporter.typeError(4977_error, _identifier.location, "Expected a library."); return size_t(-1); } } @@ -774,6 +789,7 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) if (!externalCall || externalCall->annotation().kind != FunctionCallKind::FunctionCall) { m_errorReporter.typeError( + 5347_error, _tryStatement.externalCall().location(), "Try can only be used with external function calls and contract creation calls." ); @@ -788,6 +804,7 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) ) { m_errorReporter.typeError( + 2536_error, _tryStatement.externalCall().location(), "Try can only be used with external function calls and contract creation calls." ); @@ -810,6 +827,7 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) successClause.parameters()->parameters(); if (returnTypes.size() != parameters.size()) m_errorReporter.typeError( + 2800_error, successClause.location(), "Function returns " + to_string(functionType.returnParameterTypes().size()) + @@ -823,6 +841,7 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) solAssert(returnTypes[i], ""); if (parameters[i] && *parameters[i]->annotation().type != *returnTypes[i]) m_errorReporter.typeError( + 6509_error, parameters[i]->location(), "Invalid type, expected " + returnTypes[i]->toString(false) + @@ -842,6 +861,7 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) { if (lowLevelClause) m_errorReporter.typeError( + 5320_error, clause.location(), SecondarySourceLocation{}.append("The first clause is here:", lowLevelClause->location()), "This try statement already has a low-level catch clause." @@ -853,9 +873,10 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) clause.parameters()->parameters().size() != 1 || *clause.parameters()->parameters().front()->type() != *TypeProvider::bytesMemory() ) - m_errorReporter.typeError(clause.location(), "Expected `catch (bytes memory ...) { ... }` or `catch { ... }`."); + m_errorReporter.typeError(6231_error, clause.location(), "Expected `catch (bytes memory ...) { ... }` or `catch { ... }`."); if (!m_evmVersion.supportsReturndata()) m_errorReporter.typeError( + 9908_error, clause.location(), "This catch clause type cannot be used on the selected EVM version (" + m_evmVersion.name() + @@ -867,6 +888,7 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) { if (!m_evmVersion.supportsReturndata()) m_errorReporter.typeError( + 1812_error, clause.location(), "This catch clause type cannot be used on the selected EVM version (" + m_evmVersion.name() + @@ -875,6 +897,7 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) if (errorClause) m_errorReporter.typeError( + 1036_error, clause.location(), SecondarySourceLocation{}.append("The first clause is here:", errorClause->location()), "This try statement already has an \"Error\" catch clause." @@ -885,10 +908,11 @@ void TypeChecker::endVisit(TryStatement const& _tryStatement) clause.parameters()->parameters().size() != 1 || *clause.parameters()->parameters().front()->type() != *TypeProvider::stringMemory() ) - m_errorReporter.typeError(clause.location(), "Expected `catch Error(string memory ...) { ... }`."); + m_errorReporter.typeError(2943_error, clause.location(), "Expected `catch Error(string memory ...) { ... }`."); } else m_errorReporter.typeError( + 3542_error, clause.location(), "Invalid catch clause name. Expected either `catch (...)` or `catch Error(...)`." ); @@ -920,12 +944,12 @@ void TypeChecker::endVisit(Return const& _return) if (!_return.expression()) { if (params && !params->parameters().empty()) - m_errorReporter.typeError(_return.location(), "Return arguments required."); + m_errorReporter.typeError(6777_error, _return.location(), "Return arguments required."); return; } if (!params) { - m_errorReporter.typeError(_return.location(), "Return arguments not allowed."); + m_errorReporter.typeError(7552_error, _return.location(), "Return arguments not allowed."); return; } TypePointers returnTypes; @@ -934,12 +958,13 @@ void TypeChecker::endVisit(Return const& _return) if (auto tupleType = dynamic_cast(type(*_return.expression()))) { if (tupleType->components().size() != params->parameters().size()) - m_errorReporter.typeError(_return.location(), "Different number of arguments in return statement than in returns declaration."); + m_errorReporter.typeError(5132_error, _return.location(), "Different number of arguments in return statement than in returns declaration."); else { BoolResult result = tupleType->isImplicitlyConvertibleTo(TupleType(returnTypes)); if (!result) m_errorReporter.typeErrorConcatenateDescriptions( + 5992_error, _return.expression()->location(), "Return argument type " + type(*_return.expression())->toString() + @@ -950,13 +975,14 @@ void TypeChecker::endVisit(Return const& _return) } } else if (params->parameters().size() != 1) - m_errorReporter.typeError(_return.location(), "Different number of arguments in return statement than in returns declaration."); + m_errorReporter.typeError(8863_error, _return.location(), "Different number of arguments in return statement than in returns declaration."); else { TypePointer const& expected = type(*params->parameters().front()); BoolResult result = type(*_return.expression())->isImplicitlyConvertibleTo(*expected); if (!result) m_errorReporter.typeErrorConcatenateDescriptions( + 6359_error, _return.expression()->location(), "Return argument type " + type(*_return.expression())->toString() + @@ -974,7 +1000,7 @@ void TypeChecker::endVisit(EmitStatement const& _emit) type(_emit.eventCall().expression())->category() != Type::Category::Function || dynamic_cast(*type(_emit.eventCall().expression())).kind() != FunctionType::Kind::Event ) - m_errorReporter.typeError(_emit.eventCall().expression().location(), "Expression has to be an event invocation."); + m_errorReporter.typeError(9292_error, _emit.eventCall().expression().location(), "Expression has to be an event invocation."); } namespace @@ -1042,15 +1068,16 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) } else // Bailing out *fatal* here, as those (untyped) vars may be used later, and diagnostics wouldn't be helpful then. - m_errorReporter.fatalTypeError(_statement.location(), "Use of the \"var\" keyword is disallowed."); + m_errorReporter.fatalTypeError(4626_error, _statement.location(), "Use of the \"var\" keyword is disallowed."); } VariableDeclaration const& varDecl = *_statement.declarations().front(); if (!varDecl.annotation().type) - m_errorReporter.fatalTypeError(_statement.location(), "Use of the \"var\" keyword is disallowed."); + m_errorReporter.fatalTypeError(6983_error, _statement.location(), "Use of the \"var\" keyword is disallowed."); if (dynamic_cast(type(varDecl))) m_errorReporter.typeError( + 4182_error, varDecl.location(), "Uninitialized mapping. Mappings cannot be created dynamically, you have to assign them from a state variable." ); @@ -1074,6 +1101,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) solAssert(m_errorReporter.hasErrors(), ""); else if (valueTypes.size() != variables.size()) m_errorReporter.typeError( + 7364_error, _statement.location(), "Different number of components on the left hand side (" + toString(variables.size()) + @@ -1103,6 +1131,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) { if (valueComponentType->category() == Type::Category::RationalNumber) m_errorReporter.fatalTypeError( + 6963_error, _statement.initialValue()->location(), "Invalid rational " + valueComponentType->toString() + @@ -1158,11 +1187,13 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) { if (var.annotation().type->operator==(*valueComponentType->mobileType())) m_errorReporter.typeError( + 5107_error, _statement.location(), errorMsg + ", but it can be explicitly converted." ); else m_errorReporter.typeError( + 4486_error, _statement.location(), errorMsg + ". Try converting to type " + @@ -1172,6 +1203,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) } else m_errorReporter.typeErrorConcatenateDescriptions( + 9574_error, _statement.location(), errorMsg + ".", result.message() @@ -1192,12 +1224,14 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) { if (!typeCanBeExpressed(variables)) m_errorReporter.syntaxError( + 3478_error, _statement.location(), "Use of the \"var\" keyword is disallowed. " "Type cannot be expressed in syntax." ); else m_errorReporter.syntaxError( + 1719_error, _statement.location(), "Use of the \"var\" keyword is disallowed. " "Use explicit declaration `" + createTupleDecl(variables) + " = ...ยด instead." @@ -1211,7 +1245,7 @@ void TypeChecker::endVisit(ExpressionStatement const& _statement) { if (type(_statement.expression())->category() == Type::Category::RationalNumber) if (!dynamic_cast(*type(_statement.expression())).mobileType()) - m_errorReporter.typeError(_statement.expression().location(), "Invalid rational number."); + m_errorReporter.typeError(3757_error, _statement.expression().location(), "Invalid rational number."); if (auto call = dynamic_cast(&_statement.expression())) { @@ -1224,9 +1258,9 @@ void TypeChecker::endVisit(ExpressionStatement const& _statement) kind == FunctionType::Kind::BareDelegateCall || kind == FunctionType::Kind::BareStaticCall ) - m_errorReporter.warning(_statement.location(), "Return value of low-level calls not used."); + m_errorReporter.warning(9302_error, _statement.location(), "Return value of low-level calls not used."); else if (kind == FunctionType::Kind::Send) - m_errorReporter.warning(_statement.location(), "Failure condition of 'send' ignored. Consider using 'transfer' instead."); + m_errorReporter.warning(5878_error, _statement.location(), "Failure condition of 'send' ignored. Consider using 'transfer' instead."); } } } @@ -1244,12 +1278,12 @@ bool TypeChecker::visit(Conditional const& _conditional) TypePointer commonType = nullptr; if (!trueType) - m_errorReporter.typeError(_conditional.trueExpression().location(), "Invalid mobile type in true expression."); + m_errorReporter.typeError(9717_error, _conditional.trueExpression().location(), "Invalid mobile type in true expression."); else commonType = trueType; if (!falseType) - m_errorReporter.typeError(_conditional.falseExpression().location(), "Invalid mobile type in false expression."); + m_errorReporter.typeError(3703_error, _conditional.falseExpression().location(), "Invalid mobile type in false expression."); else commonType = falseType; @@ -1262,6 +1296,7 @@ bool TypeChecker::visit(Conditional const& _conditional) if (!commonType) { m_errorReporter.typeError( + 1080_error, _conditional.location(), "True expression's type " + trueType->toString() + @@ -1283,6 +1318,7 @@ bool TypeChecker::visit(Conditional const& _conditional) if (_conditional.annotation().willBeWrittenTo) m_errorReporter.typeError( + 2212_error, _conditional.location(), "Conditional expression as left value is not supported yet." ); @@ -1295,7 +1331,7 @@ void TypeChecker::checkExpressionAssignment(Type const& _type, Expression const& if (auto const* tupleExpression = dynamic_cast(&_expression)) { if (tupleExpression->components().empty()) - m_errorReporter.typeError(_expression.location(), "Empty tuple on the left hand side."); + m_errorReporter.typeError(5547_error, _expression.location(), "Empty tuple on the left hand side."); auto const* tupleType = dynamic_cast(&_type); auto const& types = tupleType && tupleExpression->components().size() != 1 ? tupleType->components() : vector { &_type }; @@ -1320,7 +1356,7 @@ void TypeChecker::checkExpressionAssignment(Type const& _type, Expression const& if (variableDeclaration->isLocalOrReturn()) isLocalOrReturn = true; if (!isLocalOrReturn) - m_errorReporter.typeError(_expression.location(), "Mappings cannot be assigned to."); + m_errorReporter.typeError(9214_error, _expression.location(), "Mappings cannot be assigned to."); } } @@ -1339,6 +1375,7 @@ bool TypeChecker::visit(Assignment const& _assignment) { if (_assignment.assignmentOperator() != Token::Assign) m_errorReporter.typeError( + 4289_error, _assignment.location(), "Compound assignment is not allowed for tuple types." ); @@ -1363,6 +1400,7 @@ bool TypeChecker::visit(Assignment const& _assignment) ); if (!resultType || *resultType != *t) m_errorReporter.typeError( + 7366_error, _assignment.location(), "Operator " + string(TokenTraits::toString(_assignment.assignmentOperator())) + @@ -1383,7 +1421,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple) if (_tuple.annotation().willBeWrittenTo) { if (_tuple.isInlineArray()) - m_errorReporter.fatalTypeError(_tuple.location(), "Inline array type cannot be declared as LValue."); + m_errorReporter.fatalTypeError(3025_error, _tuple.location(), "Inline array type cannot be declared as LValue."); for (auto const& component: components) if (component) { @@ -1410,7 +1448,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple) for (size_t i = 0; i < components.size(); ++i) { if (!components[i]) - m_errorReporter.fatalTypeError(_tuple.location(), "Tuple component cannot be empty."); + m_errorReporter.fatalTypeError(8381_error, _tuple.location(), "Tuple component cannot be empty."); components[i]->accept(*this); types.push_back(type(*components[i])); @@ -1419,21 +1457,21 @@ bool TypeChecker::visit(TupleExpression const& _tuple) if (dynamic_cast(*types[i]).components().empty()) { if (_tuple.isInlineArray()) - m_errorReporter.fatalTypeError(components[i]->location(), "Array component cannot be empty."); - m_errorReporter.typeError(components[i]->location(), "Tuple component cannot be empty."); + m_errorReporter.fatalTypeError(5604_error, components[i]->location(), "Array component cannot be empty."); + m_errorReporter.typeError(6473_error, components[i]->location(), "Tuple component cannot be empty."); } // Note: code generation will visit each of the expression even if they are not assigned from. if (types[i]->category() == Type::Category::RationalNumber && components.size() > 1) if (!dynamic_cast(*types[i]).mobileType()) - m_errorReporter.fatalTypeError(components[i]->location(), "Invalid rational number."); + m_errorReporter.fatalTypeError(3390_error, components[i]->location(), "Invalid rational number."); if (_tuple.isInlineArray()) { solAssert(!!types[i], "Inline array cannot have empty components"); if ((i == 0 || inlineArrayType) && !types[i]->mobileType()) - m_errorReporter.fatalTypeError(components[i]->location(), "Invalid mobile type."); + m_errorReporter.fatalTypeError(9563_error, components[i]->location(), "Invalid mobile type."); if (i == 0) inlineArrayType = types[i]->mobileType(); @@ -1447,9 +1485,9 @@ bool TypeChecker::visit(TupleExpression const& _tuple) if (_tuple.isInlineArray()) { if (!inlineArrayType) - m_errorReporter.fatalTypeError(_tuple.location(), "Unable to deduce common type for array elements."); + m_errorReporter.fatalTypeError(6378_error, _tuple.location(), "Unable to deduce common type for array elements."); else if (!inlineArrayType->canLiveOutsideStorage()) - m_errorReporter.fatalTypeError(_tuple.location(), "Type " + inlineArrayType->toString() + " is only valid in storage."); + m_errorReporter.fatalTypeError(1545_error, _tuple.location(), "Type " + inlineArrayType->toString() + " is only valid in storage."); _tuple.annotation().type = TypeProvider::array(DataLocation::Memory, inlineArrayType, types.size()); } @@ -1482,9 +1520,9 @@ bool TypeChecker::visit(UnaryOperation const& _operation) if (modifying) // Cannot just report the error, ignore the unary operator, and continue, // because the sub-expression was already processed with requireLValue() - m_errorReporter.fatalTypeError(_operation.location(), description); + m_errorReporter.fatalTypeError(9767_error, _operation.location(), description); else - m_errorReporter.typeError(_operation.location(), description); + m_errorReporter.typeError(4907_error, _operation.location(), description); t = subExprType; } _operation.annotation().type = t; @@ -1501,6 +1539,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation) if (!commonType) { m_errorReporter.typeError( + 2271_error, _operation.location(), "Operator " + string(TokenTraits::toString(_operation.getOperator())) + @@ -1536,6 +1575,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation) dynamic_cast(*commonType).numBits() != 256 )) m_errorReporter.warning( + 9085_error, _operation.location(), "Result of " + operation + " has type " + commonType->toString() + " and thus " "might overflow. Silence this warning by converting the literal to the " @@ -1548,6 +1588,7 @@ void TypeChecker::endVisit(BinaryOperation const& _operation) dynamic_cast(*rightType).numBits() ) m_errorReporter.warning( + 3149_error, _operation.location(), "The result type of the " + operation + @@ -1574,11 +1615,13 @@ TypePointer TypeChecker::typeCheckTypeConversionAndRetrieveReturnType( TypePointer resultType = dynamic_cast(*expressionType).actualType(); if (arguments.size() != 1) m_errorReporter.typeError( + 2558_error, _functionCall.location(), "Exactly one argument expected for explicit type conversion." ); else if (!isPositionalCall) m_errorReporter.typeError( + 5153_error, _functionCall.location(), "Type conversion cannot allow named arguments." ); @@ -1639,6 +1682,7 @@ TypePointer TypeChecker::typeCheckTypeConversionAndRetrieveReturnType( variableDeclaration->location() ); m_errorReporter.typeError( + 7398_error, _functionCall.location(), ssl, "Explicit type conversion not allowed from non-payable \"address\" to \"" + @@ -1653,6 +1697,7 @@ TypePointer TypeChecker::typeCheckTypeConversionAndRetrieveReturnType( resultType->category() == Type::Category::Address ) m_errorReporter.typeError( + 5030_error, _functionCall.location(), "Explicit type conversion not allowed from \"" + argType->toString() + @@ -1663,6 +1708,7 @@ TypePointer TypeChecker::typeCheckTypeConversionAndRetrieveReturnType( ); else m_errorReporter.typeError( + 9640_error, _functionCall.location(), "Explicit type conversion not allowed from \"" + argType->toString() + @@ -1700,11 +1746,13 @@ void TypeChecker::typeCheckFunctionCall( !dynamic_cast(_functionType->declaration()).isImplemented() ) m_errorReporter.typeError( + 7501_error, _functionCall.location(), "Cannot call unimplemented base function." ); else m_errorReporter.typeError( + 3419_error, _functionCall.location(), "Cannot call function via contract type name." ); @@ -1717,6 +1765,7 @@ void TypeChecker::typeCheckFunctionCall( !m_evmVersion.hasStaticCall() ) m_errorReporter.typeError( + 5052_error, _functionCall.location(), "\"staticcall\" is not supported by the VM version." ); @@ -1730,25 +1779,26 @@ void TypeChecker::typeCheckFallbackFunction(FunctionDefinition const& _function) solAssert(_function.isFallback(), ""); if (_function.inContractKind() == ContractKind::Library) - m_errorReporter.typeError(_function.location(), "Libraries cannot have fallback functions."); + m_errorReporter.typeError(5982_error, _function.location(), "Libraries cannot have fallback functions."); if (_function.stateMutability() != StateMutability::NonPayable && _function.stateMutability() != StateMutability::Payable) m_errorReporter.typeError( + 4575_error, _function.location(), "Fallback function must be payable or non-payable, but is \"" + stateMutabilityToString(_function.stateMutability()) + "\"." ); if (_function.visibility() != Visibility::External) - m_errorReporter.typeError(_function.location(), "Fallback function must be defined as \"external\"."); + m_errorReporter.typeError(1159_error, _function.location(), "Fallback function must be defined as \"external\"."); if (!_function.returnParameters().empty()) { if (_function.returnParameters().size() > 1 || *type(*_function.returnParameters().front()) != *TypeProvider::bytesMemory()) - m_errorReporter.typeError(_function.returnParameterList()->location(), "Fallback function can only have a single \"bytes memory\" return value."); + m_errorReporter.typeError(5570_error, _function.returnParameterList()->location(), "Fallback function can only have a single \"bytes memory\" return value."); else - m_errorReporter.typeError(_function.returnParameterList()->location(), "Return values for fallback functions are not yet implemented."); + m_errorReporter.typeError(6151_error, _function.returnParameterList()->location(), "Return values for fallback functions are not yet implemented."); } if (!_function.parameters().empty()) - m_errorReporter.typeError(_function.parameterList().location(), "Fallback function cannot take parameters."); + m_errorReporter.typeError(3978_error, _function.parameterList().location(), "Fallback function cannot take parameters."); } void TypeChecker::typeCheckReceiveFunction(FunctionDefinition const& _function) @@ -1756,21 +1806,22 @@ void TypeChecker::typeCheckReceiveFunction(FunctionDefinition const& _function) solAssert(_function.isReceive(), ""); if (_function.inContractKind() == ContractKind::Library) - m_errorReporter.typeError(_function.location(), "Libraries cannot have receive ether functions."); + m_errorReporter.typeError(4549_error, _function.location(), "Libraries cannot have receive ether functions."); if (_function.stateMutability() != StateMutability::Payable) m_errorReporter.typeError( + 7793_error, _function.location(), "Receive ether function must be payable, but is \"" + stateMutabilityToString(_function.stateMutability()) + "\"." ); if (_function.visibility() != Visibility::External) - m_errorReporter.typeError(_function.location(), "Receive ether function must be defined as \"external\"."); + m_errorReporter.typeError(4095_error, _function.location(), "Receive ether function must be defined as \"external\"."); if (!_function.returnParameters().empty()) - m_errorReporter.typeError(_function.returnParameterList()->location(), "Receive ether function cannot return values."); + m_errorReporter.typeError(6899_error, _function.returnParameterList()->location(), "Receive ether function cannot return values."); if (!_function.parameters().empty()) - m_errorReporter.typeError(_function.parameterList().location(), "Receive ether function cannot take parameters."); + m_errorReporter.typeError(6857_error, _function.parameterList().location(), "Receive ether function cannot take parameters."); } @@ -1778,20 +1829,21 @@ void TypeChecker::typeCheckConstructor(FunctionDefinition const& _function) { solAssert(_function.isConstructor(), ""); if (_function.markedVirtual()) - m_errorReporter.typeError(_function.location(), "Constructors cannot be virtual."); + m_errorReporter.typeError(7001_error, _function.location(), "Constructors cannot be virtual."); if (_function.overrides()) - m_errorReporter.typeError(_function.location(), "Constructors cannot override."); + m_errorReporter.typeError(1209_error, _function.location(), "Constructors cannot override."); if (!_function.returnParameters().empty()) - m_errorReporter.typeError(_function.returnParameterList()->location(), "Non-empty \"returns\" directive for constructor."); + m_errorReporter.typeError(9712_error, _function.returnParameterList()->location(), "Non-empty \"returns\" directive for constructor."); if (_function.stateMutability() != StateMutability::NonPayable && _function.stateMutability() != StateMutability::Payable) m_errorReporter.typeError( + 1558_error, _function.location(), "Constructor must be payable or non-payable, but is \"" + stateMutabilityToString(_function.stateMutability()) + "\"." ); if (_function.visibility() != Visibility::Public && _function.visibility() != Visibility::Internal) - m_errorReporter.typeError(_function.location(), "Constructor must be public or internal."); + m_errorReporter.typeError(9239_error, _function.location(), "Constructor must be public or internal."); } void TypeChecker::typeCheckABIEncodeFunctions( @@ -1820,6 +1872,7 @@ void TypeChecker::typeCheckABIEncodeFunctions( if (!_functionCall.names().empty()) { m_errorReporter.typeError( + 2627_error, _functionCall.location(), "Named arguments cannot be used for functions that take arbitrary parameters." ); @@ -1841,6 +1894,7 @@ void TypeChecker::typeCheckABIEncodeFunctions( if (rationalType.isFractional()) { m_errorReporter.typeError( + 6090_error, arguments[i]->location(), "Fractional numbers cannot yet be encoded." ); @@ -1849,6 +1903,7 @@ void TypeChecker::typeCheckABIEncodeFunctions( else if (!argType->mobileType()) { m_errorReporter.typeError( + 8009_error, arguments[i]->location(), "Invalid rational number (too large or division by zero)." ); @@ -1857,6 +1912,7 @@ void TypeChecker::typeCheckABIEncodeFunctions( else if (isPacked) { m_errorReporter.typeError( + 7279_error, arguments[i]->location(), "Cannot perform packed encoding for a literal." " Please convert it to an explicit type first." @@ -1868,6 +1924,7 @@ void TypeChecker::typeCheckABIEncodeFunctions( if (isPacked && !typeSupportedByOldABIEncoder(*argType, false /* isLibrary */)) { m_errorReporter.typeError( + 9578_error, arguments[i]->location(), "Type not supported in packed mode." ); @@ -1876,6 +1933,7 @@ void TypeChecker::typeCheckABIEncodeFunctions( if (!argType->fullEncodingType(false, abiEncoderV2, !_functionType->padArguments())) m_errorReporter.typeError( + 2056_error, arguments[i]->location(), "This type cannot be encoded." ); @@ -1977,7 +2035,7 @@ void TypeChecker::typeCheckFunctionGeneralChecks( " This function requires a single bytes argument." " Use abi.encodePacked(...) to obtain the pre-0.5.0" " behaviour or abi.encode(...) to use ABI encoding."; - m_errorReporter.typeError(_functionCall.location(), msg); + m_errorReporter.typeError(1093_error, _functionCall.location(), msg); return; } @@ -2006,6 +2064,7 @@ void TypeChecker::typeCheckFunctionGeneralChecks( { duplication = true; m_errorReporter.typeError( + 6995_error, arguments[i]->location(), "Duplicate named argument \"" + *argumentNames[i] + "\"." ); @@ -2032,6 +2091,7 @@ void TypeChecker::typeCheckFunctionGeneralChecks( paramArgMap[i] = nullptr; not_all_mapped = true; m_errorReporter.typeError( + 4974_error, _functionCall.location(), "Named argument \"" + *argumentNames[i] + @@ -2077,7 +2137,7 @@ void TypeChecker::typeCheckFunctionGeneralChecks( " This function requires a single bytes argument." " Use abi.encodePacked(...) to obtain the pre-0.5.0" " behaviour or abi.encode(...) to use ABI encoding."; - m_errorReporter.typeError(paramArgMap[i]->location(), msg); + m_errorReporter.typeError(6706_error, paramArgMap[i]->location(), msg); } } } @@ -2159,7 +2219,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) } default: - m_errorReporter.fatalTypeError(_functionCall.location(), "Type is not callable"); + m_errorReporter.fatalTypeError(5704_error, _functionCall.location(), "Type is not callable"); funcCallAnno.kind = FunctionCallKind::Unset; funcCallAnno.isPure = argumentsArePure; break; @@ -2238,7 +2298,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions) auto expressionFunctionType = dynamic_cast(type(_functionCallOptions.expression())); if (!expressionFunctionType) { - m_errorReporter.fatalTypeError(_functionCallOptions.location(), "Expected callable expression before call options."); + m_errorReporter.fatalTypeError(2622_error, _functionCallOptions.location(), "Expected callable expression before call options."); return false; } @@ -2257,6 +2317,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions) ) { m_errorReporter.fatalTypeError( + 2193_error, _functionCallOptions.location(), "Function call options can only be set on external function calls or contract creations." ); @@ -2267,6 +2328,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions) { if (_option || _alreadySet) m_errorReporter.typeError( + 9886_error, _functionCallOptions.location(), _alreadySet ? "Option \"" + std::move(_name) + "\" has already been set." : @@ -2288,6 +2350,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions) } else m_errorReporter.typeError( + 2721_error, _functionCallOptions.location(), "Function call option \"salt\" can only be used with \"new\"." ); @@ -2296,16 +2359,19 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions) { if (kind == FunctionType::Kind::BareDelegateCall) m_errorReporter.typeError( + 6189_error, _functionCallOptions.location(), "Cannot set option \"value\" for delegatecall." ); else if (kind == FunctionType::Kind::BareStaticCall) m_errorReporter.typeError( + 2842_error, _functionCallOptions.location(), "Cannot set option \"value\" for staticcall." ); else if (!expressionFunctionType->isPayable()) m_errorReporter.typeError( + 7006_error, _functionCallOptions.location(), kind == FunctionType::Kind::Creation ? "Cannot set option \"value\", since the constructor of " + @@ -2324,6 +2390,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions) { if (kind == FunctionType::Kind::Creation) m_errorReporter.typeError( + 9903_error, _functionCallOptions.location(), "Function call option \"gas\" cannot be used with \"new\"." ); @@ -2336,6 +2403,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions) } else m_errorReporter.typeError( + 9318_error, _functionCallOptions.location(), "Unknown call option \"" + name + "\". Valid options are \"salt\", \"value\" and \"gas\"." ); @@ -2343,6 +2411,7 @@ bool TypeChecker::visit(FunctionCallOptions const& _functionCallOptions) if (setSalt && !m_evmVersion.hasCreate2()) m_errorReporter.typeError( + 5189_error, _functionCallOptions.location(), "Unsupported call option \"salt\" (requires Constantinople-compatible VMs)." ); @@ -2361,13 +2430,13 @@ void TypeChecker::endVisit(NewExpression const& _newExpression) auto contract = dynamic_cast(&dereference(*contractName)); if (!contract) - m_errorReporter.fatalTypeError(_newExpression.location(), "Identifier is not a contract."); + m_errorReporter.fatalTypeError(5540_error, _newExpression.location(), "Identifier is not a contract."); if (contract->isInterface()) - m_errorReporter.fatalTypeError(_newExpression.location(), "Cannot instantiate an interface."); + m_errorReporter.fatalTypeError(2971_error, _newExpression.location(), "Cannot instantiate an interface."); if (!contract->constructorIsPublic()) - m_errorReporter.typeError(_newExpression.location(), "Contract with internal constructor cannot be created directly."); + m_errorReporter.typeError(9054_error, _newExpression.location(), "Contract with internal constructor cannot be created directly."); if (contract->abstract()) - m_errorReporter.typeError(_newExpression.location(), "Cannot instantiate an abstract contract."); + m_errorReporter.typeError(4614_error, _newExpression.location(), "Cannot instantiate an abstract contract."); solAssert(!!m_scope, ""); m_scope->annotation().contractDependencies.insert(contract); @@ -2377,6 +2446,7 @@ void TypeChecker::endVisit(NewExpression const& _newExpression) ); if (contractDependenciesAreCyclic(*m_scope)) m_errorReporter.typeError( + 4579_error, _newExpression.location(), "Circular reference for contract creation (cannot create instance of derived or same contract)." ); @@ -2387,11 +2457,13 @@ void TypeChecker::endVisit(NewExpression const& _newExpression) { if (!type->canLiveOutsideStorage()) m_errorReporter.fatalTypeError( + 1164_error, _newExpression.typeName().location(), "Type cannot live outside storage." ); if (!type->isDynamicallySized()) m_errorReporter.typeError( + 3904_error, _newExpression.typeName().location(), "Length has to be placed in parentheses after the array type for new expression." ); @@ -2408,7 +2480,7 @@ void TypeChecker::endVisit(NewExpression const& _newExpression) _newExpression.annotation().isPure = true; } else - m_errorReporter.fatalTypeError(_newExpression.location(), "Contract or array type expected."); + m_errorReporter.fatalTypeError(8807_error, _newExpression.location(), "Contract or array type expected."); } bool TypeChecker::visit(MemberAccess const& _memberAccess) @@ -2447,6 +2519,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) ); if (!storageType->members(m_scope).membersByName(memberName).empty()) m_errorReporter.fatalTypeError( + 4994_error, _memberAccess.location(), "Member \"" + memberName + "\" is not available in " + exprType->toString() + @@ -2505,12 +2578,14 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) } m_errorReporter.fatalTypeError( + 4035_error, _memberAccess.location(), errorMsg ); } else if (possibleMembers.size() > 1) m_errorReporter.fatalTypeError( + 6675_error, _memberAccess.location(), "Member \"" + memberName + "\" not unique " "after argument-dependent lookup in " + exprType->toString() + @@ -2534,6 +2609,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) (memberName == "value" || memberName == "gas") ) m_errorReporter.warning( + 1621_error, _memberAccess.location(), "Using \"." + memberName + "(...)\" is deprecated. Use \"{" + memberName + ": ...}\" instead." ); @@ -2592,6 +2668,7 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) ); if (contractDependenciesAreCyclic(*m_scope)) m_errorReporter.typeError( + 4224_error, _memberAccess.location(), "Circular reference for contract code access." ); @@ -2619,7 +2696,7 @@ bool TypeChecker::visit(IndexAccess const& _access) { auto const& arrayType = dynamic_cast(*baseType).arrayType(); if (arrayType.location() != DataLocation::CallData || !arrayType.isDynamicallySized()) - m_errorReporter.typeError(_access.location(), "Index access is only implemented for slices of dynamic calldata arrays."); + m_errorReporter.typeError(4802_error, _access.location(), "Index access is only implemented for slices of dynamic calldata arrays."); baseType = &arrayType; [[fallthrough]]; } @@ -2627,10 +2704,10 @@ bool TypeChecker::visit(IndexAccess const& _access) { ArrayType const& actualType = dynamic_cast(*baseType); if (!index) - m_errorReporter.typeError(_access.location(), "Index expression cannot be omitted."); + m_errorReporter.typeError(9689_error, _access.location(), "Index expression cannot be omitted."); else if (actualType.isString()) { - m_errorReporter.typeError(_access.location(), "Index access for string is not possible."); + m_errorReporter.typeError(9961_error, _access.location(), "Index access for string is not possible."); index->accept(*this); } else @@ -2641,7 +2718,7 @@ bool TypeChecker::visit(IndexAccess const& _access) { solAssert(!numberType->isFractional(), ""); if (!actualType.isDynamicallySized() && actualType.length() <= numberType->literalValue(nullptr)) - m_errorReporter.typeError(_access.location(), "Out of bounds array access."); + m_errorReporter.typeError(3383_error, _access.location(), "Out of bounds array access."); } } resultType = actualType.baseType(); @@ -2652,7 +2729,7 @@ bool TypeChecker::visit(IndexAccess const& _access) { MappingType const& actualType = dynamic_cast(*baseType); if (!index) - m_errorReporter.typeError(_access.location(), "Index expression cannot be omitted."); + m_errorReporter.typeError(1267_error, _access.location(), "Index expression cannot be omitted."); else expectType(*index, *actualType.keyType()); resultType = actualType.valueType(); @@ -2663,7 +2740,7 @@ bool TypeChecker::visit(IndexAccess const& _access) { TypeType const& typeType = dynamic_cast(*baseType); if (dynamic_cast(typeType.actualType())) - m_errorReporter.typeError(_access.location(), "Index access for contracts or libraries is not possible."); + m_errorReporter.typeError(2876_error, _access.location(), "Index access for contracts or libraries is not possible."); if (!index) resultType = TypeProvider::typeType(TypeProvider::array(DataLocation::Memory, typeType.actualType())); else @@ -2674,7 +2751,7 @@ bool TypeChecker::visit(IndexAccess const& _access) if (auto indexValue = dynamic_cast(type(*index))) length = indexValue->literalValue(nullptr); else - m_errorReporter.fatalTypeError(index->location(), "Integer constant expected."); + m_errorReporter.fatalTypeError(3940_error, index->location(), "Integer constant expected."); } else solAssert(m_errorReporter.hasErrors(), "Expected errors as expectType returned false"); @@ -2691,14 +2768,14 @@ bool TypeChecker::visit(IndexAccess const& _access) { FixedBytesType const& bytesType = dynamic_cast(*baseType); if (!index) - m_errorReporter.typeError(_access.location(), "Index expression cannot be omitted."); + m_errorReporter.typeError(8830_error, _access.location(), "Index expression cannot be omitted."); else { if (!expectType(*index, *TypeProvider::uint256())) - m_errorReporter.fatalTypeError(_access.location(), "Index expression cannot be represented as an unsigned integer."); + m_errorReporter.fatalTypeError(6318_error, _access.location(), "Index expression cannot be represented as an unsigned integer."); if (auto integerType = dynamic_cast(type(*index))) if (bytesType.numBytes() <= integerType->literalValue(nullptr)) - m_errorReporter.typeError(_access.location(), "Out of bounds array access."); + m_errorReporter.typeError(1859_error, _access.location(), "Out of bounds array access."); } resultType = TypeProvider::fixedBytes(1); isLValue = false; // @todo this heavily depends on how it is embedded @@ -2706,6 +2783,7 @@ bool TypeChecker::visit(IndexAccess const& _access) } default: m_errorReporter.fatalTypeError( + 2614_error, _access.baseExpression().location(), "Indexed expression has to be a type, mapping or array (is " + baseType->toString() + ")" ); @@ -2742,7 +2820,7 @@ bool TypeChecker::visit(IndexRangeAccess const& _access) TypePointer exprType = type(_access.baseExpression()); if (exprType->category() == Type::Category::TypeType) { - m_errorReporter.typeError(_access.location(), "Types cannot be sliced."); + m_errorReporter.typeError(1760_error, _access.location(), "Types cannot be sliced."); _access.annotation().type = exprType; return false; } @@ -2751,11 +2829,11 @@ bool TypeChecker::visit(IndexRangeAccess const& _access) if (auto const* arraySlice = dynamic_cast(exprType)) arrayType = &arraySlice->arrayType(); else if (!(arrayType = dynamic_cast(exprType))) - m_errorReporter.fatalTypeError(_access.location(), "Index range access is only possible for arrays and array slices."); + m_errorReporter.fatalTypeError(4781_error, _access.location(), "Index range access is only possible for arrays and array slices."); if (arrayType->location() != DataLocation::CallData || !arrayType->isDynamicallySized()) - m_errorReporter.typeError(_access.location(), "Index range access is only supported for dynamic calldata arrays."); + m_errorReporter.typeError(1227_error, _access.location(), "Index range access is only supported for dynamic calldata arrays."); _access.annotation().type = TypeProvider::arraySlice(*arrayType); _access.annotation().isLValue = isLValue; _access.annotation().isPure = isPure; @@ -2790,7 +2868,7 @@ vector TypeChecker::cleanOverloadedDeclarations( for (TypePointer parameter: functionType->parameterTypes() + functionType->returnParameterTypes()) if (!parameter) - m_errorReporter.fatalDeclarationError(_identifier.location(), "Function type can not be used in this context."); + m_errorReporter.fatalDeclarationError(3893_error, _identifier.location(), "Function type can not be used in this context."); if (uniqueDeclarations.end() == find_if( uniqueDeclarations.begin(), @@ -2825,14 +2903,14 @@ bool TypeChecker::visit(Identifier const& _identifier) candidates.push_back(declaration); } if (candidates.empty()) - m_errorReporter.fatalTypeError(_identifier.location(), "No matching declaration found after variable lookup."); + m_errorReporter.fatalTypeError(2144_error, _identifier.location(), "No matching declaration found after variable lookup."); else if (candidates.size() == 1) annotation.referencedDeclaration = candidates.front(); else - m_errorReporter.fatalTypeError(_identifier.location(), "No unique declaration found after variable lookup."); + m_errorReporter.fatalTypeError(7589_error, _identifier.location(), "No unique declaration found after variable lookup."); } else if (annotation.overloadedDeclarations.empty()) - m_errorReporter.fatalTypeError(_identifier.location(), "No candidates for overload resolution found."); + m_errorReporter.fatalTypeError(7593_error, _identifier.location(), "No candidates for overload resolution found."); else if (annotation.overloadedDeclarations.size() == 1) annotation.referencedDeclaration = *annotation.overloadedDeclarations.begin(); else @@ -2866,9 +2944,9 @@ bool TypeChecker::visit(Identifier const& _identifier) else ssl.append("Candidate:", declaration->location()); if (candidates.empty()) - m_errorReporter.fatalTypeError(_identifier.location(), ssl, "No matching declaration found after argument-dependent lookup."); + m_errorReporter.fatalTypeError(9322_error, _identifier.location(), ssl, "No matching declaration found after argument-dependent lookup."); else - m_errorReporter.fatalTypeError(_identifier.location(), ssl, "No unique declaration found after argument-dependent lookup."); + m_errorReporter.fatalTypeError(4487_error, _identifier.location(), ssl, "No unique declaration found after argument-dependent lookup."); } } } @@ -2896,11 +2974,13 @@ bool TypeChecker::visit(Identifier const& _identifier) { if (_identifier.name() == "sha3" && fType->kind() == FunctionType::Kind::KECCAK256) m_errorReporter.typeError( + 3557_error, _identifier.location(), "\"sha3\" has been deprecated in favour of \"keccak256\"." ); else if (_identifier.name() == "suicide" && fType->kind() == FunctionType::Kind::Selfdestruct) m_errorReporter.typeError( + 8050_error, _identifier.location(), "\"suicide\" has been deprecated in favour of \"selfdestruct\"." ); @@ -2938,6 +3018,7 @@ void TypeChecker::endVisit(Literal const& _literal) if (!msg.empty()) m_errorReporter.syntaxError( + 9429_error, _literal.location(), msg + " If this is not used as an address, please prepend '00'. " + @@ -2947,6 +3028,7 @@ void TypeChecker::endVisit(Literal const& _literal) if (_literal.isHexNumber() && _literal.subDenomination() != Literal::SubDenomination::None) m_errorReporter.fatalTypeError( + 5145_error, _literal.location(), "Hexadecimal numbers cannot be used with unit denominations. " "You can use an expression of the form \"0x1234 * 1 day\" instead." @@ -2954,6 +3036,7 @@ void TypeChecker::endVisit(Literal const& _literal) if (_literal.subDenomination() == Literal::SubDenomination::Year) m_errorReporter.typeError( + 4820_error, _literal.location(), "Using \"years\" as a unit denomination is deprecated." ); @@ -2962,7 +3045,7 @@ void TypeChecker::endVisit(Literal const& _literal) _literal.annotation().type = TypeProvider::forLiteral(_literal); if (!_literal.annotation().type) - m_errorReporter.fatalTypeError(_literal.location(), "Invalid literal value."); + m_errorReporter.fatalTypeError(2826_error, _literal.location(), "Invalid literal value."); _literal.annotation().isPure = true; } @@ -3012,11 +3095,13 @@ bool TypeChecker::expectType(Expression const& _expression, Type const& _expecte { if (_expectedType.operator==(*type(_expression)->mobileType())) m_errorReporter.typeError( + 4426_error, _expression.location(), errorMsg + ", but it can be explicitly converted." ); else m_errorReporter.typeError( + 2326_error, _expression.location(), errorMsg + ". Try converting to type " + @@ -3025,7 +3110,7 @@ bool TypeChecker::expectType(Expression const& _expression, Type const& _expecte ); } else - m_errorReporter.typeError(_expression.location(), errorMsg + "."); + m_errorReporter.typeError(7407_error, _expression.location(), errorMsg + "."); return false; } return true; @@ -3040,7 +3125,8 @@ void TypeChecker::requireLValue(Expression const& _expression, bool _ordinaryAss if (_expression.annotation().isLValue) return; - return m_errorReporter.typeError(_expression.location(), [&]() { + return m_errorReporter.typeError( + 1123_error,_expression.location(), [&]() { if (_expression.annotation().isConstant) return "Cannot assign to a constant variable."; diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index 0d87fdbc2..645425107 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -171,6 +171,7 @@ void ViewPureChecker::endVisit(FunctionDefinition const& _funDef) !_funDef.overrides() ) m_errorReporter.warning( + 2018_error, _funDef.location(), "Function state mutability can be restricted to " + stateMutabilityToString(m_bestMutabilityAndLocation.mutability) ); @@ -252,6 +253,7 @@ void ViewPureChecker::reportMutability( )) { m_errorReporter.typeError( + 2527_error, _location, "Function declared as pure, but this expression (potentially) reads from the " "environment or state and thus requires \"view\"." @@ -261,6 +263,7 @@ void ViewPureChecker::reportMutability( else if (_mutability == StateMutability::NonPayable) { m_errorReporter.typeError( + 8961_error, _location, "Function declared as " + stateMutabilityToString(m_currentFunction->stateMutability()) + @@ -277,12 +280,14 @@ void ViewPureChecker::reportMutability( { if (_nestedLocation) m_errorReporter.typeError( + 4006_error, _location, SecondarySourceLocation().append("\"msg.value\" or \"callvalue()\" appear here inside the modifier.", *_nestedLocation), "This modifier uses \"msg.value\" or \"callvalue()\" and thus the function has to be payable or internal." ); else m_errorReporter.typeError( + 5887_error, _location, "\"msg.value\" and \"callvalue()\" can only be used in payable public functions. Make the function " "\"payable\" or use an internal function to avoid this error." diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index 13a19694b..e8fc331fa 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -44,6 +44,7 @@ BMC::BMC( if (_enabledSolvers.some()) if (!_smtlib2Responses.empty()) m_errorReporter.warning( + 5622_error, "SMT-LIB2 query responses were given in the auxiliary input, " "but this Solidity binary uses an SMT solver (Z3/CVC4) directly." "These responses will be ignored." @@ -74,6 +75,7 @@ void BMC::analyze(SourceUnit const& _source, set _safeAsserti { m_noSolverWarning = true; m_outerErrorReporter.warning( + 8084_error, SourceLocation(), "BMC analysis was not possible since no integrated SMT solver (Z3 or CVC4) was found." ); @@ -467,6 +469,7 @@ void BMC::internalOrExternalFunctionCall(FunctionCall const& _funCall) inlineFunctionCall(_funCall); else if (funType.kind() == FunctionType::Kind::Internal) m_errorReporter.warning( + 5729_error, _funCall.location(), "Assertion checker does not yet implement this type of function call." ); @@ -760,6 +763,7 @@ void BMC::checkCondition( for (auto const& eval: sortedModel) modelMessage << " " << eval.first << " = " << eval.second << "\n"; m_errorReporter.warning( + 4334_error, _location, message.str(), SecondarySourceLocation().append(modelMessage.str(), SourceLocation{}) @@ -770,20 +774,20 @@ void BMC::checkCondition( else { message << "."; - m_errorReporter.warning(_location, message.str(), secondaryLocation); + m_errorReporter.warning(6084_error, _location, message.str(), secondaryLocation); } break; } case smt::CheckResult::UNSATISFIABLE: break; case smt::CheckResult::UNKNOWN: - m_errorReporter.warning(_location, _description + " might happen here.", secondaryLocation); + m_errorReporter.warning(5225_error, _location, _description + " might happen here.", secondaryLocation); break; case smt::CheckResult::CONFLICTING: - m_errorReporter.warning(_location, "At least two SMT solvers provided conflicting answers. Results might not be sound."); + m_errorReporter.warning(1584_error, _location, "At least two SMT solvers provided conflicting answers. Results might not be sound."); break; case smt::CheckResult::ERROR: - m_errorReporter.warning(_location, "Error trying to invoke SMT solver."); + m_errorReporter.warning(1823_error, _location, "Error trying to invoke SMT solver."); break; } @@ -813,9 +817,9 @@ void BMC::checkBooleanNotConstant( m_interface->pop(); if (positiveResult == smt::CheckResult::ERROR || negatedResult == smt::CheckResult::ERROR) - m_errorReporter.warning(_condition.location(), "Error trying to invoke SMT solver."); + m_errorReporter.warning(8592_error, _condition.location(), "Error trying to invoke SMT solver."); else if (positiveResult == smt::CheckResult::CONFLICTING || negatedResult == smt::CheckResult::CONFLICTING) - m_errorReporter.warning(_condition.location(), "At least two SMT solvers provided conflicting answers. Results might not be sound."); + m_errorReporter.warning(3356_error, _condition.location(), "At least two SMT solvers provided conflicting answers. Results might not be sound."); else if (positiveResult == smt::CheckResult::SATISFIABLE && negatedResult == smt::CheckResult::SATISFIABLE) { // everything fine. @@ -825,7 +829,7 @@ void BMC::checkBooleanNotConstant( // can't do anything. } else if (positiveResult == smt::CheckResult::UNSATISFIABLE && negatedResult == smt::CheckResult::UNSATISFIABLE) - m_errorReporter.warning(_condition.location(), "Condition unreachable.", SMTEncoder::callStackMessage(_callStack)); + m_errorReporter.warning(2512_error, _condition.location(), "Condition unreachable.", SMTEncoder::callStackMessage(_callStack)); else { string value; @@ -841,6 +845,7 @@ void BMC::checkBooleanNotConstant( value = "false"; } m_errorReporter.warning( + 6838_error, _condition.location(), boost::algorithm::replace_all_copy(_description, "$VALUE", value), SMTEncoder::callStackMessage(_callStack) @@ -862,7 +867,7 @@ BMC::checkSatisfiableAndGenerateModel(vector const& _expression string description("Error querying SMT solver"); if (_e.comment()) description += ": " + *_e.comment(); - m_errorReporter.warning(description); + m_errorReporter.warning(8140_error, description); result = smt::CheckResult::ERROR; } diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 59e77d7cd..1453df34f 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -965,10 +965,10 @@ pair> CHC::query(smt::Expression const& _query, case smt::CheckResult::UNKNOWN: break; case smt::CheckResult::CONFLICTING: - m_outerErrorReporter.warning(_location, "At least two SMT solvers provided conflicting answers. Results might not be sound."); + m_outerErrorReporter.warning(1988_error, _location, "At least two SMT solvers provided conflicting answers. Results might not be sound."); break; case smt::CheckResult::ERROR: - m_outerErrorReporter.warning(_location, "Error trying to invoke SMT solver."); + m_outerErrorReporter.warning(1218_error, _location, "Error trying to invoke SMT solver."); break; } return {result, values}; diff --git a/libsolidity/formal/SMTEncoder.cpp b/libsolidity/formal/SMTEncoder.cpp index 9003d26ce..8760c7b6b 100644 --- a/libsolidity/formal/SMTEncoder.cpp +++ b/libsolidity/formal/SMTEncoder.cpp @@ -266,6 +266,7 @@ void SMTEncoder::endVisit(FunctionDefinition const&) bool SMTEncoder::visit(InlineAssembly const& _inlineAsm) { m_errorReporter.warning( + 7737_error, _inlineAsm.location(), "Assertion checker does not support inline assembly." ); @@ -325,6 +326,7 @@ void SMTEncoder::endVisit(VariableDeclarationStatement const& _varDecl) } else m_errorReporter.warning( + 7186_error, _varDecl.location(), "Assertion checker does not yet implement such variable declarations." ); @@ -350,6 +352,7 @@ void SMTEncoder::endVisit(Assignment const& _assignment) m_context.newValue(*varDecl); m_errorReporter.warning( + 9149_error, _assignment.location(), "Assertion checker does not yet implement this assignment operator." ); @@ -409,6 +412,7 @@ void SMTEncoder::endVisit(TupleExpression const& _tuple) if (_tuple.isInlineArray()) m_errorReporter.warning( + 2177_error, _tuple.location(), "Assertion checker does not yet implement inline arrays." ); @@ -493,6 +497,7 @@ void SMTEncoder::endVisit(UnaryOperation const& _op) } else m_errorReporter.warning( + 1950_error, _op.location(), "Assertion checker does not yet implement such increments / decrements." ); @@ -522,6 +527,7 @@ void SMTEncoder::endVisit(UnaryOperation const& _op) arrayIndexAssignment(_op.subExpression(), symbVar->currentValue()); else m_errorReporter.warning( + 2683_error, _op.location(), "Assertion checker does not yet implement \"delete\" for this expression." ); @@ -530,6 +536,7 @@ void SMTEncoder::endVisit(UnaryOperation const& _op) } default: m_errorReporter.warning( + 3682_error, _op.location(), "Assertion checker does not yet implement this operator." ); @@ -568,6 +575,7 @@ void SMTEncoder::endVisit(BinaryOperation const& _op) compareOperation(_op); else m_errorReporter.warning( + 3876_error, _op.location(), "Assertion checker does not yet implement this operator." ); @@ -580,6 +588,7 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall) if (_funCall.annotation().kind == FunctionCallKind::StructConstructorCall) { m_errorReporter.warning( + 4639_error, _funCall.location(), "Assertion checker does not yet implement this expression." ); @@ -639,6 +648,7 @@ void SMTEncoder::endVisit(FunctionCall const& _funCall) } default: m_errorReporter.warning( + 4588_error, _funCall.location(), "Assertion checker does not yet implement this type of function call." ); @@ -771,6 +781,7 @@ void SMTEncoder::visitTypeConversion(FunctionCall const& _funCall) } m_errorReporter.warning( + 5084_error, _funCall.location(), "Type conversion is not yet fully supported and might yield false positives." ); @@ -800,6 +811,7 @@ void SMTEncoder::endVisit(Literal const& _literal) else { m_errorReporter.warning( + 7885_error, _literal.location(), "Assertion checker does not yet support the type of this literal (" + _literal.annotation().type->toString() + @@ -850,6 +862,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess) accessedName = identifier->name(); else m_errorReporter.warning( + 9551_error, _memberAccess.location(), "Assertion checker does not yet support this expression." ); @@ -879,6 +892,7 @@ bool SMTEncoder::visit(MemberAccess const& _memberAccess) } else m_errorReporter.warning( + 7650_error, _memberAccess.location(), "Assertion checker does not yet support this expression." ); @@ -903,6 +917,7 @@ void SMTEncoder::endVisit(IndexAccess const& _indexAccess) if (varDecl->type()->category() == Type::Category::FixedBytes) { m_errorReporter.warning( + 7989_error, _indexAccess.location(), "Assertion checker does not yet support index accessing fixed bytes." ); @@ -917,6 +932,7 @@ void SMTEncoder::endVisit(IndexAccess const& _indexAccess) else { m_errorReporter.warning( + 9118_error, _indexAccess.location(), "Assertion checker does not yet implement this expression." ); @@ -940,6 +956,7 @@ void SMTEncoder::endVisit(IndexRangeAccess const& _indexRangeAccess) { createExpr(_indexRangeAccess); m_errorReporter.warning( + 2923_error, _indexRangeAccess.location(), "Assertion checker does not yet implement this expression." ); @@ -1019,6 +1036,7 @@ void SMTEncoder::arrayIndexAssignment(Expression const& _expr, smt::Expression c else { m_errorReporter.warning( + 9056_error, _expr.location(), "Assertion checker does not yet implement this expression." ); @@ -1034,6 +1052,7 @@ void SMTEncoder::defineGlobalVariable(string const& _name, Expression const& _ex bool abstract = m_context.createGlobalSymbol(_name, _expr); if (abstract) m_errorReporter.warning( + 1695_error, _expr.location(), "Assertion checker does not yet support this global variable." ); @@ -1087,6 +1106,7 @@ void SMTEncoder::arithmeticOperation(BinaryOperation const& _op) } default: m_errorReporter.warning( + 5188_error, _op.location(), "Assertion checker does not yet implement this operator." ); @@ -1094,6 +1114,7 @@ void SMTEncoder::arithmeticOperation(BinaryOperation const& _op) } else m_errorReporter.warning( + 9011_error, _op.location(), "Assertion checker does not yet implement this operator for type " + type->richIdentifier() + "." ); @@ -1185,6 +1206,7 @@ void SMTEncoder::compareOperation(BinaryOperation const& _op) } else m_errorReporter.warning( + 7229_error, _op.location(), "Assertion checker does not yet implement the type " + _op.annotation().commonType->toString() + " for comparisons" ); @@ -1213,6 +1235,7 @@ void SMTEncoder::booleanOperation(BinaryOperation const& _op) } else m_errorReporter.warning( + 3263_error, _op.location(), "Assertion checker does not yet implement the type " + _op.annotation().commonType->toString() + " for boolean operations" ); @@ -1245,6 +1268,7 @@ void SMTEncoder::assignment( m_context.newValue(*varDecl); m_errorReporter.warning( + 6191_error, _location, "Assertion checker does not yet implement type " + _type->toString() ); @@ -1272,6 +1296,7 @@ void SMTEncoder::assignment( } else m_errorReporter.warning( + 8182_error, _location, "Assertion checker does not yet implement such assignments." ); @@ -1482,6 +1507,7 @@ bool SMTEncoder::createVariable(VariableDeclaration const& _varDecl) if (abstract) { m_errorReporter.warning( + 8115_error, _varDecl.location(), "Assertion checker does not yet support the type of this variable." ); @@ -1494,7 +1520,7 @@ smt::Expression SMTEncoder::expr(Expression const& _e, TypePointer _targetType) { if (!m_context.knownExpression(_e)) { - m_errorReporter.warning(_e.location(), "Internal error: Expression undefined for SMT solver." ); + m_errorReporter.warning(6031_error, _e.location(), "Internal error: Expression undefined for SMT solver." ); createExpr(_e); } @@ -1506,6 +1532,7 @@ void SMTEncoder::createExpr(Expression const& _e) bool abstract = m_context.createExpression(_e); if (abstract) m_errorReporter.warning( + 8364_error, _e.location(), "Assertion checker does not yet implement type " + _e.annotation().type->toString() ); diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index 0af68bda7..519eea81a 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -239,7 +239,7 @@ bool CompilerStack::parse() m_errorReporter.clear(); if (SemVerVersion{string(VersionString)}.isPrerelease()) - m_errorReporter.warning("This is a pre-release compiler version, please do not use it in production."); + m_errorReporter.warning(3805_error, "This is a pre-release compiler version, please do not use it in production."); Parser parser{m_errorReporter, m_evmVersion, m_parserErrorRecovery}; @@ -949,6 +949,7 @@ StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string else { m_errorReporter.parserError( + 6275_error, import->location(), string("Source \"" + importPath + "\" not found: " + result.responseOrErrorMessage) ); @@ -1110,6 +1111,7 @@ void CompilerStack::compileContract( compiledContract.runtimeObject.bytecode.size() > 0x6000 ) m_errorReporter.warning( + 5574_error, _contract.location(), "Contract code size exceeds 24576 bytes (a limit introduced in Spurious Dragon). " "This contract may not be deployable on mainnet. " diff --git a/libsolidity/parsing/DocStringParser.cpp b/libsolidity/parsing/DocStringParser.cpp index fb1468197..b8238554f 100644 --- a/libsolidity/parsing/DocStringParser.cpp +++ b/libsolidity/parsing/DocStringParser.cpp @@ -195,5 +195,5 @@ void DocStringParser::newTag(string const& _tagName) void DocStringParser::appendError(string const& _description) { m_errorsOccurred = true; - m_errorReporter->docstringParsingError(_description); + m_errorReporter->docstringParsingError(9440_error, _description); } diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index d3c4a2cdd..d24b0e69f 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -128,6 +128,7 @@ void Parser::parsePragmaVersion(SourceLocation const& _location, vector c // so we don't need to report anything here. if (!m_parserErrorRecovery) m_errorReporter.fatalParserError( + 5333_error, _location, "Source file requires different compiler version (current compiler is " + string(VersionString) + ") - note that nightly builds are considered to be " diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 7858b70c4..5c6b7c927 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -583,6 +583,7 @@ bool AsmAnalyzer::warnOnInstructions(evmasm::Instruction _instr, SourceLocation ) { m_errorReporter.error( + 4316_error, Error::Type::SyntaxError, _location, "Jump instructions and labels are low-level EVM features that can lead to " @@ -599,13 +600,13 @@ bool AsmAnalyzer::warnOnInstructions(evmasm::Instruction _instr, SourceLocation void AsmAnalyzer::typeError(SourceLocation const& _location, string const& _description) { - m_errorReporter.typeError(_location, _description); + m_errorReporter.typeError(7569_error, _location, _description); m_success = false; } void AsmAnalyzer::declarationError(SourceLocation const& _location, string const& _description) { - m_errorReporter.declarationError(_location, _description); + m_errorReporter.declarationError(9595_error, _location, _description); m_success = false; } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 99a3a6e21..13b96839b 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -151,7 +151,7 @@ Statement Parser::parseStatement() { Statement stmt{createWithLocation()}; if (!m_insideFunction) - m_errorReporter.syntaxError(currentLocation(), "Keyword \"leave\" can only be used inside a function."); + m_errorReporter.syntaxError(8149_error, currentLocation(), "Keyword \"leave\" can only be used inside a function."); m_scanner->next(); return stmt; } @@ -417,6 +417,7 @@ FunctionDefinition Parser::parseFunctionDefinition() if (m_currentForLoopComponent == ForLoopComponent::ForLoopPre) m_errorReporter.syntaxError( + 3441_error, currentLocation(), "Functions cannot be defined inside a for-loop init block." ); @@ -534,13 +535,13 @@ void Parser::checkBreakContinuePosition(string const& _which) switch (m_currentForLoopComponent) { case ForLoopComponent::None: - m_errorReporter.syntaxError(currentLocation(), "Keyword \"" + _which + "\" needs to be inside a for-loop body."); + m_errorReporter.syntaxError(2592_error, currentLocation(), "Keyword \"" + _which + "\" needs to be inside a for-loop body."); break; case ForLoopComponent::ForLoopPre: - m_errorReporter.syntaxError(currentLocation(), "Keyword \"" + _which + "\" in for-loop init block is not allowed."); + m_errorReporter.syntaxError(9615_error, currentLocation(), "Keyword \"" + _which + "\" in for-loop init block is not allowed."); break; case ForLoopComponent::ForLoopPost: - m_errorReporter.syntaxError(currentLocation(), "Keyword \"" + _which + "\" in for-loop post block is not allowed."); + m_errorReporter.syntaxError(2461_error, currentLocation(), "Keyword \"" + _which + "\" in for-loop post block is not allowed."); break; case ForLoopComponent::ForLoopBody: break; diff --git a/libyul/AsmScopeFiller.cpp b/libyul/AsmScopeFiller.cpp index 4c37bf5ec..62d00435f 100644 --- a/libyul/AsmScopeFiller.cpp +++ b/libyul/AsmScopeFiller.cpp @@ -141,6 +141,7 @@ bool ScopeFiller::registerVariable(TypedName const& _name, SourceLocation const& { //@TODO secondary location m_errorReporter.declarationError( + 1395_error, _location, "Variable name " + _name.name.str() + " already taken in this scope." ); @@ -161,6 +162,7 @@ bool ScopeFiller::registerFunction(FunctionDefinition const& _funDef) { //@TODO secondary location m_errorReporter.declarationError( + 6052_error, _funDef.location, "Function name " + _funDef.name.str() + " already taken in this scope." );