From e72fa7fc10f951d94310383deb9d11845928ceee Mon Sep 17 00:00:00 2001 From: Leo Alt Date: Wed, 30 Jun 2021 14:48:45 +0200 Subject: [PATCH] Add new info severity --- docs/security-considerations.rst | 4 ++ docs/using-the-compiler.rst | 5 +- liblangutil/ErrorReporter.cpp | 19 ++++++ liblangutil/ErrorReporter.h | 8 ++- liblangutil/Exceptions.cpp | 3 + liblangutil/Exceptions.h | 68 ++++++++++++++++--- liblangutil/ParserBase.h | 2 +- liblangutil/SourceReferenceExtractor.cpp | 8 +-- liblangutil/SourceReferenceExtractor.h | 6 +- liblangutil/SourceReferenceFormatter.cpp | 6 +- liblangutil/SourceReferenceFormatter.h | 4 +- libsolidity/analysis/ContractLevelChecker.cpp | 4 +- libsolidity/analysis/ControlFlowAnalyzer.cpp | 2 +- libsolidity/analysis/ControlFlowGraph.cpp | 2 +- libsolidity/analysis/PostTypeChecker.cpp | 4 +- .../analysis/PostTypeContractLevelChecker.cpp | 2 +- libsolidity/analysis/StaticAnalyzer.cpp | 2 +- libsolidity/analysis/SyntaxChecker.cpp | 2 +- libsolidity/analysis/TypeChecker.cpp | 2 +- libsolidity/interface/CompilerStack.cpp | 4 +- libsolidity/interface/StandardCompiler.cpp | 42 ++++++------ scripts/error_codes.py | 2 +- solc/CommandLineInterface.cpp | 2 +- test/libsolidity/AnalysisFramework.cpp | 12 ++-- test/libsolidity/AnalysisFramework.h | 4 +- test/libsolidity/Assembly.cpp | 8 +-- test/libsolidity/InlineAssembly.cpp | 2 +- test/libsolidity/SolidityParser.cpp | 2 +- test/libsolidity/StandardCompiler.cpp | 15 +++- test/libsolidity/SyntaxTest.cpp | 2 +- test/libyul/ControlFlowGraphTest.cpp | 2 +- test/libyul/ObjectParser.cpp | 14 ++-- test/libyul/Parser.cpp | 14 ++-- test/libyul/StackLayoutGeneratorTest.cpp | 2 +- test/libyul/YulOptimizerTest.cpp | 2 +- test/tools/ossfuzz/YulEvmoneInterface.cpp | 2 +- test/tools/ossfuzz/yulProtoFuzzer.cpp | 2 +- test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp | 2 +- 38 files changed, 191 insertions(+), 97 deletions(-) diff --git a/docs/security-considerations.rst b/docs/security-considerations.rst index 0fab056ff..09770c570 100644 --- a/docs/security-considerations.rst +++ b/docs/security-considerations.rst @@ -389,6 +389,10 @@ code. Always use the latest version of the compiler to be notified about all recently introduced warnings. +Messages of type ``info`` issued by the compiler are not dangerous, and simply +represent extra suggestions and optional information that the compiler thinks +might be useful to the user. + Restrict the Amount of Ether ============================ diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 2ca338041..5245991fd 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -437,7 +437,7 @@ Output Description .. code-block:: javascript { - // Optional: not present if no errors/warnings were encountered + // Optional: not present if no errors/warnings/infos were encountered "errors": [ { // Optional: Location within the source file. @@ -460,7 +460,7 @@ Output Description "type": "TypeError", // Mandatory: Component where the error originated, such as "general", "ewasm", etc. "component": "general", - // Mandatory ("error" or "warning") + // Mandatory ("error", "warning" or "info", but please note that this may be extended in the future) "severity": "error", // Optional: unique code for the cause of the error "errorCode": "3141", @@ -604,6 +604,7 @@ Error Types 11. ``CompilerError``: Invalid use of the compiler stack - this should be reported as an issue. 12. ``FatalError``: Fatal error not processed correctly - this should be reported as an issue. 13. ``Warning``: A warning, which didn't stop the compilation, but should be addressed if possible. +14. ``Info``: Information that the compiler thinks the user might find useful, but is not dangerous and does not necessarily need to be addressed. .. _compiler-tools: diff --git a/liblangutil/ErrorReporter.cpp b/liblangutil/ErrorReporter.cpp index 728c9dad9..02487034a 100644 --- a/liblangutil/ErrorReporter.cpp +++ b/liblangutil/ErrorReporter.cpp @@ -94,6 +94,16 @@ bool ErrorReporter::checkForExcessiveErrors(Error::Type _type) if (m_warningCount >= c_maxWarningsAllowed) return true; } + else if (_type == Error::Type::Info) + { + m_infoCount++; + + if (m_infoCount == c_maxInfosAllowed) + m_errorList.push_back(make_shared(2833_error, Error::Type::Info, "There are more than 256 infos. Ignoring the rest.")); + + if (m_infoCount >= c_maxInfosAllowed) + return true; + } else { m_errorCount++; @@ -242,3 +252,12 @@ void ErrorReporter::docstringParsingError(ErrorId _error, SourceLocation const& _description ); } + +void ErrorReporter::info( + ErrorId _error, + SourceLocation const& _location, + string const& _description +) +{ + error(_error, Error::Type::Info, _location, _description); +} diff --git a/liblangutil/ErrorReporter.h b/liblangutil/ErrorReporter.h index 7cdce0caa..6f91f0713 100644 --- a/liblangutil/ErrorReporter.h +++ b/liblangutil/ErrorReporter.h @@ -63,6 +63,8 @@ public: SecondarySourceLocation const& _secondaryLocation ); + void info(ErrorId _error, SourceLocation const& _location, std::string const& _description); + void error( ErrorId _error, Error::Type _type, @@ -118,13 +120,13 @@ public: void clear(); - /// @returns true iff there is any error (ignores warnings). + /// @returns true iff there is any error (ignores warnings and infos). bool hasErrors() const { return m_errorCount > 0; } - /// @returns the number of errors (ignores warnings). + /// @returns the number of errors (ignores warnings and infos). unsigned errorCount() const { return m_errorCount; @@ -183,9 +185,11 @@ private: unsigned m_errorCount = 0; unsigned m_warningCount = 0; + unsigned m_infoCount = 0; unsigned const c_maxWarningsAllowed = 256; unsigned const c_maxErrorsAllowed = 256; + unsigned const c_maxInfosAllowed = 256; }; } diff --git a/liblangutil/Exceptions.cpp b/liblangutil/Exceptions.cpp index 3caa81b1d..34aa69803 100644 --- a/liblangutil/Exceptions.cpp +++ b/liblangutil/Exceptions.cpp @@ -47,6 +47,9 @@ Error::Error( case Type::DocstringParsingError: m_typeName = "DocstringParsingError"; break; + case Type::Info: + m_typeName = "Info"; + break; case Type::ParserError: m_typeName = "ParserError"; break; diff --git a/liblangutil/Exceptions.h b/liblangutil/Exceptions.h index c7385bac8..68f109717 100644 --- a/liblangutil/Exceptions.h +++ b/liblangutil/Exceptions.h @@ -120,7 +120,15 @@ public: ParserError, TypeError, SyntaxError, - Warning + Warning, + Info + }; + + enum class Severity + { + Error, + Warning, + Info }; Error( @@ -139,21 +147,63 @@ public: static Error const* containsErrorOfType(ErrorList const& _list, Error::Type _type) { for (auto e: _list) - { if (e->type() == _type) return e.get(); - } return nullptr; } - static bool containsOnlyWarnings(ErrorList const& _list) + + static Severity errorSeverity(Type _type) + { + if (_type == Type::Info) + return Severity::Info; + if (_type == Type::Warning) + return Severity::Warning; + return Severity::Error; + } + + static bool isError(Severity _severity) + { + return _severity == Severity::Error; + } + + static bool isError(Type _type) + { + return isError(errorSeverity(_type)); + } + + static bool containsErrors(ErrorList const& _list) { for (auto e: _list) - { - if (e->type() != Type::Warning) - return false; - } - return true; + if (isError(e->type())) + return true; + return false; } + + static std::string formatErrorSeverity(Severity _severity) + { + if (_severity == Severity::Info) + return "Info"; + if (_severity == Severity::Warning) + return "Warning"; + solAssert(isError(_severity), ""); + return "Error"; + } + + static std::string formatErrorSeverityLowercase(Severity _severity) + { + switch (_severity) + { + case Severity::Info: + return "info"; + case Severity::Warning: + return "warning"; + case Severity::Error: + solAssert(isError(_severity), ""); + return "error"; + } + solAssert(false, ""); + } + private: ErrorId m_errorId; Type m_type; diff --git a/liblangutil/ParserBase.h b/liblangutil/ParserBase.h index 6c5ce081b..f72400f6c 100644 --- a/liblangutil/ParserBase.h +++ b/liblangutil/ParserBase.h @@ -104,7 +104,7 @@ protected: void fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description); std::shared_ptr m_scanner; - /// The reference to the list of errors and warning to add errors/warnings during parsing + /// The reference to the list of errors, warnings and infos to add errors/warnings/infos during parsing ErrorReporter& m_errorReporter; /// Current recursion depth during parsing. size_t m_recursionDepth = 0; diff --git a/liblangutil/SourceReferenceExtractor.cpp b/liblangutil/SourceReferenceExtractor.cpp index 717e590df..373ad6b18 100644 --- a/liblangutil/SourceReferenceExtractor.cpp +++ b/liblangutil/SourceReferenceExtractor.cpp @@ -30,7 +30,7 @@ using namespace solidity::langutil; SourceReferenceExtractor::Message SourceReferenceExtractor::extract( CharStreamProvider const& _charStreamProvider, util::Exception const& _exception, - string _category + string _severity ) { SourceLocation const* location = boost::get_error_info(_exception); @@ -44,7 +44,7 @@ SourceReferenceExtractor::Message SourceReferenceExtractor::extract( for (auto const& info: secondaryLocation->infos) secondary.emplace_back(extract(_charStreamProvider, &info.second, info.first)); - return Message{std::move(primary), _category, std::move(secondary), nullopt}; + return Message{std::move(primary), _severity, std::move(secondary), nullopt}; } SourceReferenceExtractor::Message SourceReferenceExtractor::extract( @@ -52,8 +52,8 @@ SourceReferenceExtractor::Message SourceReferenceExtractor::extract( Error const& _error ) { - string category = (_error.type() == Error::Type::Warning) ? "Warning" : "Error"; - Message message = extract(_charStreamProvider, _error, category); + string severity = Error::formatErrorSeverity(Error::errorSeverity(_error.type())); + Message message = extract(_charStreamProvider, _error, severity); message.errorId = _error.errorId(); return message; } diff --git a/liblangutil/SourceReferenceExtractor.h b/liblangutil/SourceReferenceExtractor.h index d26a941f5..6aeb6065e 100644 --- a/liblangutil/SourceReferenceExtractor.h +++ b/liblangutil/SourceReferenceExtractor.h @@ -41,7 +41,7 @@ struct LineColumn struct SourceReference { - std::string message; ///< A message that relates to this source reference (such as a warning or an error message). + std::string message; ///< A message that relates to this source reference (such as a warning, info or an error message). std::string sourceName; ///< Underlying source name (for example the filename). LineColumn position; ///< Actual (error) position this source reference is surrounding. bool multiline = {false}; ///< Indicates whether the actual SourceReference is truncated to one line. @@ -64,12 +64,12 @@ namespace SourceReferenceExtractor struct Message { SourceReference primary; - std::string category; // "Error", "Warning", ... + std::string severity; // "Error", "Warning", "Info", ... std::vector secondary; std::optional errorId; }; - Message extract(CharStreamProvider const& _charStreamProvider, util::Exception const& _exception, std::string _category); + Message extract(CharStreamProvider const& _charStreamProvider, util::Exception const& _exception, std::string _severity); Message extract(CharStreamProvider const& _charStreamProvider, Error const& _error); SourceReference extract(CharStreamProvider const& _charStreamProvider, SourceLocation const* _location, std::string message = ""); } diff --git a/liblangutil/SourceReferenceFormatter.cpp b/liblangutil/SourceReferenceFormatter.cpp index 20d0f3306..623e13dd1 100644 --- a/liblangutil/SourceReferenceFormatter.cpp +++ b/liblangutil/SourceReferenceFormatter.cpp @@ -164,7 +164,7 @@ void SourceReferenceFormatter::printSourceLocation(SourceReference const& _ref) void SourceReferenceFormatter::printExceptionInformation(SourceReferenceExtractor::Message const& _msg) { // exception header line - errorColored() << _msg.category; + errorColored() << _msg.severity; if (m_withErrorIds && _msg.errorId.has_value()) errorColored() << " (" << _msg.errorId.value().error << ")"; messageColored() << ": " << _msg.primary.message << '\n'; @@ -181,9 +181,9 @@ void SourceReferenceFormatter::printExceptionInformation(SourceReferenceExtracto m_stream << '\n'; } -void SourceReferenceFormatter::printExceptionInformation(util::Exception const& _exception, std::string const& _category) +void SourceReferenceFormatter::printExceptionInformation(util::Exception const& _exception, std::string const& _severity) { - printExceptionInformation(SourceReferenceExtractor::extract(m_charStreamProvider, _exception, _category)); + printExceptionInformation(SourceReferenceExtractor::extract(m_charStreamProvider, _exception, _severity)); } void SourceReferenceFormatter::printErrorInformation(ErrorList const& _errors) diff --git a/liblangutil/SourceReferenceFormatter.h b/liblangutil/SourceReferenceFormatter.h index fc1f418a2..5bac03a9a 100644 --- a/liblangutil/SourceReferenceFormatter.h +++ b/liblangutil/SourceReferenceFormatter.h @@ -52,7 +52,7 @@ public: /// Prints source location if it is given. void printSourceLocation(SourceReference const& _ref); void printExceptionInformation(SourceReferenceExtractor::Message const& _msg); - void printExceptionInformation(util::Exception const& _exception, std::string const& _category); + void printExceptionInformation(util::Exception const& _exception, std::string const& _severity); void printErrorInformation(langutil::ErrorList const& _errors); void printErrorInformation(Error const& _error); @@ -77,7 +77,7 @@ public: { return formatExceptionInformation( _error, - (_error.type() == Error::Type::Warning) ? "Warning" : "Error", + Error::formatErrorSeverity(Error::errorSeverity(_error.type())), _charStreamProvider ); } diff --git a/libsolidity/analysis/ContractLevelChecker.cpp b/libsolidity/analysis/ContractLevelChecker.cpp index 631545569..c159b8357 100644 --- a/libsolidity/analysis/ContractLevelChecker.cpp +++ b/libsolidity/analysis/ContractLevelChecker.cpp @@ -71,7 +71,7 @@ bool ContractLevelChecker::check(SourceUnit const& _sourceUnit) findDuplicateDefinitions( filterDeclarations(*_sourceUnit.annotation().exportedSymbols) ); - if (!Error::containsOnlyWarnings(m_errorReporter.errors())) + if (Error::containsErrors(m_errorReporter.errors())) noErrors = false; for (ASTPointer const& node: _sourceUnit.nodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) @@ -97,7 +97,7 @@ bool ContractLevelChecker::check(ContractDefinition const& _contract) checkPayableFallbackWithoutReceive(_contract); checkStorageSize(_contract); - return Error::containsOnlyWarnings(m_errorReporter.errors()); + return !Error::containsErrors(m_errorReporter.errors()); } void ContractLevelChecker::checkDuplicateFunctions(ContractDefinition const& _contract) diff --git a/libsolidity/analysis/ControlFlowAnalyzer.cpp b/libsolidity/analysis/ControlFlowAnalyzer.cpp index 181943032..0c64ac3b5 100644 --- a/libsolidity/analysis/ControlFlowAnalyzer.cpp +++ b/libsolidity/analysis/ControlFlowAnalyzer.cpp @@ -36,7 +36,7 @@ bool ControlFlowAnalyzer::run() for (auto& [pair, flow]: m_cfg.allFunctionFlows()) analyze(*pair.function, pair.contract, *flow); - return Error::containsOnlyWarnings(m_errorReporter.errors()); + return !Error::containsErrors(m_errorReporter.errors()); } void ControlFlowAnalyzer::analyze(FunctionDefinition const& _function, ContractDefinition const* _contract, FunctionFlow const& _flow) diff --git a/libsolidity/analysis/ControlFlowGraph.cpp b/libsolidity/analysis/ControlFlowGraph.cpp index 66ec552ca..f4afe0149 100644 --- a/libsolidity/analysis/ControlFlowGraph.cpp +++ b/libsolidity/analysis/ControlFlowGraph.cpp @@ -27,7 +27,7 @@ using namespace solidity::frontend; bool CFG::constructFlow(ASTNode const& _astRoot) { _astRoot.accept(*this); - return Error::containsOnlyWarnings(m_errorReporter.errors()); + return !Error::containsErrors(m_errorReporter.errors()); } diff --git a/libsolidity/analysis/PostTypeChecker.cpp b/libsolidity/analysis/PostTypeChecker.cpp index e5c3ec2f8..cdc8c8b7e 100644 --- a/libsolidity/analysis/PostTypeChecker.cpp +++ b/libsolidity/analysis/PostTypeChecker.cpp @@ -36,14 +36,14 @@ using namespace solidity::frontend; bool PostTypeChecker::check(ASTNode const& _astRoot) { _astRoot.accept(*this); - return Error::containsOnlyWarnings(m_errorReporter.errors()); + return !Error::containsErrors(m_errorReporter.errors()); } bool PostTypeChecker::finalize() { for (auto& checker: m_checkers) checker->finalize(); - return Error::containsOnlyWarnings(m_errorReporter.errors()); + return !Error::containsErrors(m_errorReporter.errors()); } bool PostTypeChecker::visit(ContractDefinition const& _contractDefinition) diff --git a/libsolidity/analysis/PostTypeContractLevelChecker.cpp b/libsolidity/analysis/PostTypeContractLevelChecker.cpp index cfc6f4f29..32927188f 100644 --- a/libsolidity/analysis/PostTypeContractLevelChecker.cpp +++ b/libsolidity/analysis/PostTypeContractLevelChecker.cpp @@ -68,5 +68,5 @@ bool PostTypeContractLevelChecker::check(ContractDefinition const& _contract) errorHashes[hash][signature] = error->location(); } - return Error::containsOnlyWarnings(m_errorReporter.errors()); + return !Error::containsErrors(m_errorReporter.errors()); } diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp index 4931401cb..01ca601f1 100644 --- a/libsolidity/analysis/StaticAnalyzer.cpp +++ b/libsolidity/analysis/StaticAnalyzer.cpp @@ -86,7 +86,7 @@ StaticAnalyzer::~StaticAnalyzer() bool StaticAnalyzer::analyze(SourceUnit const& _sourceUnit) { _sourceUnit.accept(*this); - return Error::containsOnlyWarnings(m_errorReporter.errors()); + return !Error::containsErrors(m_errorReporter.errors()); } bool StaticAnalyzer::visit(ContractDefinition const& _contract) diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index 412ad1aa9..e47080cb4 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -41,7 +41,7 @@ using namespace solidity::util; bool SyntaxChecker::checkSyntax(ASTNode const& _astRoot) { _astRoot.accept(*this); - return Error::containsOnlyWarnings(m_errorReporter.errors()); + return !Error::containsErrors(m_errorReporter.errors()); } bool SyntaxChecker::visit(SourceUnit const& _sourceUnit) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 369e04bc9..afcf92525 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -73,7 +73,7 @@ bool TypeChecker::checkTypeRequirements(SourceUnit const& _source) m_currentSourceUnit = &_source; _source.accept(*this); m_currentSourceUnit = nullptr; - return Error::containsOnlyWarnings(m_errorReporter.errors()); + return !Error::containsErrors(m_errorReporter.errors()); } Type const* TypeChecker::type(Expression const& _expression) const diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index cbdfff454..722e76fe5 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -338,7 +338,7 @@ bool CompilerStack::parse() Source& source = m_sources[path]; source.ast = parser.parse(*source.charStream); if (!source.ast) - solAssert(!Error::containsOnlyWarnings(m_errorReporter.errors()), "Parser returned null but did not report error."); + solAssert(Error::containsErrors(m_errorReporter.errors()), "Parser returned null but did not report error."); else { source.ast->annotation().path = path; @@ -357,7 +357,7 @@ bool CompilerStack::parse() m_stackState = Parsed; else m_stackState = ParsedAndImported; - if (!Error::containsOnlyWarnings(m_errorReporter.errors())) + if (Error::containsErrors(m_errorReporter.errors())) m_hasError = true; storeContractDefinitions(); diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 4071a1fbe..4d4dba6ca 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -50,7 +50,7 @@ namespace { Json::Value formatError( - bool _warning, + Error::Severity _severity, string const& _type, string const& _component, string const& _message, @@ -62,7 +62,7 @@ Json::Value formatError( Json::Value error = Json::objectValue; error["type"] = _type; error["component"] = _component; - error["severity"] = _warning ? "warning" : "error"; + error["severity"] = Error::formatErrorSeverityLowercase(_severity); error["message"] = _message; error["formattedMessage"] = (_formattedMessage.length() > 0) ? _formattedMessage : _message; if (_sourceLocation.isObject()) @@ -76,7 +76,7 @@ Json::Value formatFatalError(string const& _type, string const& _message) { Json::Value output = Json::objectValue; output["errors"] = Json::arrayValue; - output["errors"].append(formatError(false, _type, "general", _message)); + output["errors"].append(formatError(Error::Severity::Error, _type, "general", _message)); return output; } @@ -111,7 +111,7 @@ Json::Value formatSecondarySourceLocation(SecondarySourceLocation const* _second Json::Value formatErrorWithException( CharStreamProvider const& _charStreamProvider, util::Exception const& _exception, - bool const& _warning, + Error::Severity _severity, string const& _type, string const& _component, string const& _message, @@ -132,7 +132,7 @@ Json::Value formatErrorWithException( message = _message; Json::Value error = formatError( - _warning, + _severity, _type, _component, message, @@ -660,7 +660,7 @@ std::variant StandardCompiler: string content = sources[sourceName]["content"].asString(); if (!hash.empty() && !hashMatchesContent(hash, content)) ret.errors.append(formatError( - false, + Error::Severity::Error, "IOError", "general", "Mismatch between content and supplied hash for \"" + sourceName + "\"" @@ -685,7 +685,7 @@ std::variant StandardCompiler: { if (!hash.empty() && !hashMatchesContent(hash, result.responseOrErrorMessage)) ret.errors.append(formatError( - false, + Error::Severity::Error, "IOError", "general", "Mismatch between content and supplied hash for \"" + sourceName + "\" at \"" + url.asString() + "\"" @@ -705,7 +705,7 @@ std::variant StandardCompiler: { /// If the import succeeded, let mark all the others as warnings, otherwise all of them are errors. ret.errors.append(formatError( - found ? true : false, + found ? Error::Severity::Warning : Error::Severity::Error, "IOError", "general", failure @@ -1058,7 +1058,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting errors.append(formatErrorWithException( compilerStack, *error, - err.type() == Error::Type::Warning, + Error::errorSeverity(err.type()), err.typeName(), "general", "", @@ -1072,7 +1072,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting errors.append(formatErrorWithException( compilerStack, _error, - false, + Error::Severity::Error, _error.typeName(), "general", "Uncaught error: " @@ -1082,7 +1082,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting catch (FatalError const& _exception) { errors.append(formatError( - false, + Error::Severity::Error, "FatalError", "general", "Uncaught fatal error: " + boost::diagnostic_information(_exception) @@ -1093,7 +1093,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting errors.append(formatErrorWithException( compilerStack, _exception, - false, + Error::Severity::Error, "CompilerError", "general", "Compiler error (" + _exception.lineInfo() + ")" @@ -1104,7 +1104,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting errors.append(formatErrorWithException( compilerStack, _exception, - false, + Error::Severity::Error, "InternalCompilerError", "general", "Internal compiler error (" + _exception.lineInfo() + ")" @@ -1115,7 +1115,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting errors.append(formatErrorWithException( compilerStack, _exception, - false, + Error::Severity::Error, "UnimplementedFeatureError", "general", "Unimplemented feature (" + _exception.lineInfo() + ")" @@ -1126,7 +1126,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting errors.append(formatErrorWithException( compilerStack, _exception, - false, + Error::Severity::Error, "YulException", "general", "Yul exception" @@ -1137,7 +1137,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting errors.append(formatErrorWithException( compilerStack, _exception, - false, + Error::Severity::Error, "SMTLogicException", "general", "SMT logic exception" @@ -1146,7 +1146,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting catch (util::Exception const& _exception) { errors.append(formatError( - false, + Error::Severity::Error, "Exception", "general", "Exception during compilation: " + boost::diagnostic_information(_exception) @@ -1155,7 +1155,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting catch (std::exception const& _e) { errors.append(formatError( - false, + Error::Severity::Error, "Exception", "general", "Unknown exception during compilation" + (_e.what() ? ": " + string(_e.what()) : ".") @@ -1164,7 +1164,7 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting catch (...) { errors.append(formatError( - false, + Error::Severity::Error, "Exception", "general", "Unknown exception during compilation." @@ -1345,7 +1345,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) errors.append(formatErrorWithException( stack, *error, - err->type() == Error::Type::Warning, + Error::errorSeverity(err->type()), err->typeName(), "general", "" @@ -1357,7 +1357,7 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings) // TODO: move this warning to AssemblyStack output["errors"] = Json::arrayValue; - output["errors"].append(formatError(true, "Warning", "general", "Yul is still experimental. Please use the output with care.")); + output["errors"].append(formatError(Error::Severity::Warning, "Warning", "general", "Yul is still experimental. Please use the output with care.")); string contractName = stack.parserResult()->name.str(); diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 6f3f9ce95..4167a00f5 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -226,7 +226,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): old_source_only_ids = { "1584", "1823", - "1988", "2066", "3356", + "1988", "2066", "2833", "3356", "3893", "3996", "4010", "4802", "5272", "5622", "7128", "7400", "7589", "7593", "7649", "7710", diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 275451114..c7fb6258b 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -976,7 +976,7 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul: m_hasOutput = true; formatter.printErrorInformation(*error); } - if (!Error::containsOnlyWarnings(stack.errors())) + if (Error::containsErrors(stack.errors())) successful = false; } diff --git a/test/libsolidity/AnalysisFramework.cpp b/test/libsolidity/AnalysisFramework.cpp index bc1a5372d..84c7a5e0b 100644 --- a/test/libsolidity/AnalysisFramework.cpp +++ b/test/libsolidity/AnalysisFramework.cpp @@ -75,24 +75,24 @@ AnalysisFramework::parseAnalyseAndReturnError( return make_pair(&compiler().ast(""), std::move(errors)); } -ErrorList AnalysisFramework::filterErrors(ErrorList const& _errorList, bool _includeWarnings) const +ErrorList AnalysisFramework::filterErrors(ErrorList const& _errorList, bool _includeWarningsAndInfos) const { ErrorList errors; for (auto const& currentError: _errorList) { solAssert(currentError->comment(), ""); - if (currentError->type() == Error::Type::Warning) + if (!Error::isError(currentError->type())) { - if (!_includeWarnings) + if (!_includeWarningsAndInfos) continue; - bool ignoreWarning = false; + bool ignoreWarningsAndInfos = false; for (auto const& filter: m_warningsToFilter) if (currentError->comment()->find(filter) == 0) { - ignoreWarning = true; + ignoreWarningsAndInfos = true; break; } - if (ignoreWarning) + if (ignoreWarningsAndInfos) continue; } diff --git a/test/libsolidity/AnalysisFramework.h b/test/libsolidity/AnalysisFramework.h index 17554b9ac..c4b4eda33 100644 --- a/test/libsolidity/AnalysisFramework.h +++ b/test/libsolidity/AnalysisFramework.h @@ -66,8 +66,8 @@ protected: std::string const& _signature ); - // filter out the warnings in m_warningsToFilter or all warnings if _includeWarnings is false - langutil::ErrorList filterErrors(langutil::ErrorList const& _errorList, bool _includeWarnings) const; + // filter out the warnings in m_warningsToFilter or all warnings and infos if _includeWarningsAndInfos is false + langutil::ErrorList filterErrors(langutil::ErrorList const& _errorList, bool _includeWarningsAndInfos) const; std::vector m_warningsToFilter = {"This is a pre-release compiler version"}; std::vector m_messagesToCut = {"Source file requires different compiler version (current compiler is"}; diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp index 76b1ba2a6..f12c12ca9 100644 --- a/test/libsolidity/Assembly.cpp +++ b/test/libsolidity/Assembly.cpp @@ -67,20 +67,20 @@ evmasm::AssemblyItems compileContract(std::shared_ptr _sourceCode) GlobalContext globalContext; NameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), errorReporter); DeclarationTypeChecker declarationTypeChecker(errorReporter, solidity::test::CommonOptions::get().evmVersion()); - solAssert(Error::containsOnlyWarnings(errorReporter.errors()), ""); + solAssert(!Error::containsErrors(errorReporter.errors()), ""); resolver.registerDeclarations(*sourceUnit); BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*sourceUnit)); - if (!Error::containsOnlyWarnings(errorReporter.errors())) + if (Error::containsErrors(errorReporter.errors())) return AssemblyItems(); for (ASTPointer const& node: sourceUnit->nodes()) { BOOST_REQUIRE_NO_THROW(declarationTypeChecker.check(*node)); - if (!Error::containsOnlyWarnings(errorReporter.errors())) + if (Error::containsErrors(errorReporter.errors())) return AssemblyItems(); } TypeChecker checker(solidity::test::CommonOptions::get().evmVersion(), errorReporter); BOOST_REQUIRE_NO_THROW(checker.checkTypeRequirements(*sourceUnit)); - if (!Error::containsOnlyWarnings(errorReporter.errors())) + if (Error::containsErrors(errorReporter.errors())) return AssemblyItems(); for (ASTPointer const& node: sourceUnit->nodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 19b2da3b3..0ec9b50a2 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -128,7 +128,7 @@ void parsePrintCompare(string const& _source, bool _canWarn = false) AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none()); BOOST_REQUIRE(stack.parseAndAnalyze("", _source)); if (_canWarn) - BOOST_REQUIRE(Error::containsOnlyWarnings(stack.errors())); + BOOST_REQUIRE(!Error::containsErrors(stack.errors())); else BOOST_REQUIRE(stack.errors().empty()); string expectation = "object \"object\" {\n code " + boost::replace_all_copy(_source, "\n", "\n ") + "\n}\n"; diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index 58024d9a6..77c01f1ea 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -74,7 +74,7 @@ bool successParse(std::string const& _source) if (Error::containsErrorOfType(errors, Error::Type::ParserError)) return false; - BOOST_CHECK(Error::containsOnlyWarnings(errors)); + BOOST_CHECK(!Error::containsErrors(errors)); return true; } diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp index 8787d1173..ec5166cb1 100644 --- a/test/libsolidity/StandardCompiler.cpp +++ b/test/libsolidity/StandardCompiler.cpp @@ -41,6 +41,19 @@ namespace solidity::frontend::test namespace { +langutil::Error::Severity str2Severity(string const& _cat) +{ + map cats{ + {"info", langutil::Error::Severity::Info}, + {"Info", langutil::Error::Severity::Info}, + {"warning", langutil::Error::Severity::Warning}, + {"Warning", langutil::Error::Severity::Warning}, + {"error", langutil::Error::Severity::Error}, + {"Error", langutil::Error::Severity::Error} + }; + return cats.at(_cat); +} + /// Helper to match a specific error type and message bool containsError(Json::Value const& _compilerResult, string const& _type, string const& _message) { @@ -68,7 +81,7 @@ bool containsAtMostWarnings(Json::Value const& _compilerResult) { BOOST_REQUIRE(error.isObject()); BOOST_REQUIRE(error["severity"].isString()); - if (error["severity"].asString() != "warning") + if (langutil::Error::isError(str2Severity(error["severity"].asString()))) return false; } diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp index bc0f6a7d8..2a70c35ab 100644 --- a/test/libsolidity/SyntaxTest.cpp +++ b/test/libsolidity/SyntaxTest.cpp @@ -91,7 +91,7 @@ void SyntaxTest::parseAndAnalyze() return error->type() == Error::Type::CodeGenerationError; }); auto errorCount = count_if(errors.cbegin(), errors.cend(), [](auto const& error) { - return error->type() != Error::Type::Warning; + return Error::isError(error->type()); }); // failing compilation after successful analysis is a rare case, // it assumes that errors contain exactly one error, and the error is of type Error::Type::CodeGenerationError diff --git a/test/libyul/ControlFlowGraphTest.cpp b/test/libyul/ControlFlowGraphTest.cpp index c77c190d3..dffc7ecbf 100644 --- a/test/libyul/ControlFlowGraphTest.cpp +++ b/test/libyul/ControlFlowGraphTest.cpp @@ -200,7 +200,7 @@ TestCase::TestResult ControlFlowGraphTest::run(ostream& _stream, string const& _ { ErrorList errors; auto [object, analysisInfo] = parse(m_source, *m_dialect, errors); - if (!object || !analysisInfo || !Error::containsOnlyWarnings(errors)) + if (!object || !analysisInfo || Error::containsErrors(errors)) { AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl; return TestResult::FatalError; diff --git a/test/libyul/ObjectParser.cpp b/test/libyul/ObjectParser.cpp index 987933a9f..d70d2002c 100644 --- a/test/libyul/ObjectParser.cpp +++ b/test/libyul/ObjectParser.cpp @@ -72,7 +72,7 @@ pair parse(string const& _source) return {false, {}}; } -optional parseAndReturnFirstError(string const& _source, bool _allowWarnings = true) +optional parseAndReturnFirstError(string const& _source, bool _allowWarningsAndInfos = true) { bool success; ErrorList errors; @@ -85,11 +85,11 @@ optional parseAndReturnFirstError(string const& _source, bool _allowWarni else { // If success is true, there might still be an error in the assembly stage. - if (_allowWarnings && Error::containsOnlyWarnings(errors)) + if (_allowWarningsAndInfos && !Error::containsErrors(errors)) return {}; else if (!errors.empty()) { - if (!_allowWarnings) + if (!_allowWarningsAndInfos) BOOST_CHECK_EQUAL(errors.size(), 1); return *errors.front(); } @@ -97,15 +97,15 @@ optional parseAndReturnFirstError(string const& _source, bool _allowWarni return {}; } -bool successParse(string const& _source, bool _allowWarnings = true) +bool successParse(string const& _source, bool _allowWarningsAndInfos = true) { - return !parseAndReturnFirstError(_source, _allowWarnings); + return !parseAndReturnFirstError(_source, _allowWarningsAndInfos); } -Error expectError(string const& _source, bool _allowWarnings = false) +Error expectError(string const& _source, bool _allowWarningsAndInfos = false) { - auto error = parseAndReturnFirstError(_source, _allowWarnings); + auto error = parseAndReturnFirstError(_source, _allowWarningsAndInfos); BOOST_REQUIRE(error); return *error; } diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index 4168b23a3..0ac9e64c9 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -85,7 +85,7 @@ shared_ptr parse(string const& _source, Dialect const& _dialect, ErrorRep return {}; } -std::optional parseAndReturnFirstError(string const& _source, Dialect const& _dialect, bool _allowWarnings = true) +std::optional parseAndReturnFirstError(string const& _source, Dialect const& _dialect, bool _allowWarningsAndInfos = true) { ErrorList errors; ErrorReporter errorReporter(errors); @@ -98,11 +98,11 @@ std::optional parseAndReturnFirstError(string const& _source, Dialect con else { // If success is true, there might still be an error in the assembly stage. - if (_allowWarnings && Error::containsOnlyWarnings(errors)) + if (_allowWarningsAndInfos && !Error::containsErrors(errors)) return {}; else if (!errors.empty()) { - if (!_allowWarnings) + if (!_allowWarningsAndInfos) BOOST_CHECK_EQUAL(errors.size(), 1); return *errors.front(); } @@ -110,15 +110,15 @@ std::optional parseAndReturnFirstError(string const& _source, Dialect con return {}; } -bool successParse(std::string const& _source, Dialect const& _dialect = Dialect::yulDeprecated(), bool _allowWarnings = true) +bool successParse(std::string const& _source, Dialect const& _dialect = Dialect::yulDeprecated(), bool _allowWarningsAndInfos = true) { - return !parseAndReturnFirstError(_source, _dialect, _allowWarnings); + return !parseAndReturnFirstError(_source, _dialect, _allowWarningsAndInfos); } -Error expectError(std::string const& _source, Dialect const& _dialect = Dialect::yulDeprecated(), bool _allowWarnings = false) +Error expectError(std::string const& _source, Dialect const& _dialect = Dialect::yulDeprecated(), bool _allowWarningsAndInfos = false) { - auto error = parseAndReturnFirstError(_source, _dialect, _allowWarnings); + auto error = parseAndReturnFirstError(_source, _dialect, _allowWarningsAndInfos); BOOST_REQUIRE(error); return *error; } diff --git a/test/libyul/StackLayoutGeneratorTest.cpp b/test/libyul/StackLayoutGeneratorTest.cpp index 35d4c07ee..70fda680e 100644 --- a/test/libyul/StackLayoutGeneratorTest.cpp +++ b/test/libyul/StackLayoutGeneratorTest.cpp @@ -217,7 +217,7 @@ TestCase::TestResult StackLayoutGeneratorTest::run(ostream& _stream, string cons { ErrorList errors; auto [object, analysisInfo] = parse(m_source, *m_dialect, errors); - if (!object || !analysisInfo || !Error::containsOnlyWarnings(errors)) + if (!object || !analysisInfo || Error::containsErrors(errors)) { AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl; return TestResult::FatalError; diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index ada942152..6404fa7c6 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -114,7 +114,7 @@ std::pair, std::shared_ptr> YulOptimize shared_ptr object; shared_ptr analysisInfo; std::tie(object, analysisInfo) = yul::test::parse(_source, *m_dialect, errors); - if (!object || !analysisInfo || !Error::containsOnlyWarnings(errors)) + if (!object || !analysisInfo || Error::containsErrors(errors)) { AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl; CharStream charStream(_source, ""); diff --git a/test/tools/ossfuzz/YulEvmoneInterface.cpp b/test/tools/ossfuzz/YulEvmoneInterface.cpp index fe737993d..e21a881c6 100644 --- a/test/tools/ossfuzz/YulEvmoneInterface.cpp +++ b/test/tools/ossfuzz/YulEvmoneInterface.cpp @@ -29,7 +29,7 @@ bytes YulAssembler::assemble() !m_stack.parseAndAnalyze("source", m_yulProgram) || !m_stack.parserResult()->code || !m_stack.parserResult()->analysisInfo || - !langutil::Error::containsOnlyWarnings(m_stack.errors()) + langutil::Error::containsErrors(m_stack.errors()) ) yulAssert(false, "Yul program could not be parsed successfully."); diff --git a/test/tools/ossfuzz/yulProtoFuzzer.cpp b/test/tools/ossfuzz/yulProtoFuzzer.cpp index a3b4e14ee..7118a0596 100644 --- a/test/tools/ossfuzz/yulProtoFuzzer.cpp +++ b/test/tools/ossfuzz/yulProtoFuzzer.cpp @@ -72,7 +72,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) !stack.parseAndAnalyze("source", yul_source) || !stack.parserResult()->code || !stack.parserResult()->analysisInfo || - !Error::containsOnlyWarnings(stack.errors()) + Error::containsErrors(stack.errors()) ) yulAssert(false, "Proto fuzzer generated malformed program"); diff --git a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp index 1fe4e6eaa..abb0df82f 100644 --- a/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/yulProto_diff_ossfuzz.cpp @@ -71,7 +71,7 @@ DEFINE_PROTO_FUZZER(Program const& _input) !stack.parseAndAnalyze("source", yul_source) || !stack.parserResult()->code || !stack.parserResult()->analysisInfo || - !Error::containsOnlyWarnings(stack.errors()) + Error::containsErrors(stack.errors()) ) { SourceReferenceFormatter formatter(std::cout, stack, false, false);