diff options
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.cpp | 5 | ||||
-rw-r--r-- | libsolidity/analysis/SyntaxChecker.cpp | 6 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 18 | ||||
-rw-r--r-- | libsolidity/ast/ASTJsonConverter.cpp | 3 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerContext.cpp | 2 | ||||
-rw-r--r-- | libsolidity/codegen/ExpressionCompiler.cpp | 6 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.cpp | 13 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.cpp | 7 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmParser.h | 3 | ||||
-rw-r--r-- | libsolidity/interface/AssemblyStack.cpp | 2 | ||||
-rw-r--r-- | libsolidity/interface/SourceReferenceFormatter.cpp | 55 | ||||
-rw-r--r-- | libsolidity/interface/SourceReferenceFormatter.h | 38 | ||||
-rw-r--r-- | libsolidity/interface/StandardCompiler.cpp | 13 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.cpp | 2 |
14 files changed, 100 insertions, 73 deletions
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 5e4d414b..662792a3 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -457,9 +457,10 @@ bool DeclarationRegistrationHelper::registerDeclaration( if (!_errorLocation) _errorLocation = &_declaration.location(); + string name = _name ? *_name : _declaration.name(); Declaration const* shadowedDeclaration = nullptr; - if (_warnOnShadow && !_declaration.name().empty() && _container.enclosingContainer()) - for (auto const* decl: _container.enclosingContainer()->resolveName(_declaration.name(), true)) + if (_warnOnShadow && !name.empty() && _container.enclosingContainer()) + for (auto const* decl: _container.enclosingContainer()->resolveName(name, true)) shadowedDeclaration = decl; if (!_container.registerDeclaration(_declaration, _name, !_declaration.isVisibleInContract())) diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index 5a3745b0..74834ba4 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -93,8 +93,10 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma) m_errorReporter.syntaxError(_pragma.location(), "Duplicate experimental feature name."); else { - m_sourceUnit->annotation().experimentalFeatures.insert(ExperimentalFeatureNames.at(literal)); - m_errorReporter.warning(_pragma.location(), "Experimental features are turned on. Do not use experimental features on live deployments."); + auto feature = ExperimentalFeatureNames.at(literal); + m_sourceUnit->annotation().experimentalFeatures.insert(feature); + if (!ExperimentalFeatureOnlyAnalysis.count(feature)) + m_errorReporter.warning(_pragma.location(), "Experimental features are turned on. Do not use experimental features on live deployments."); } } } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index d67142e4..0ee16c89 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -804,7 +804,12 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) solAssert(!!declaration, ""); if (auto var = dynamic_cast<VariableDeclaration const*>(declaration)) { - if (ref->second.isSlot || ref->second.isOffset) + if (var->isConstant()) + { + m_errorReporter.typeError(_identifier.location, "Constant variables not supported by inline assembly."); + return size_t(-1); + } + else if (ref->second.isSlot || ref->second.isOffset) { if (!var->isStateVariable() && !var->type()->dataStoredIn(DataLocation::Storage)) { @@ -817,11 +822,6 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly) return size_t(-1); } } - else if (var->isConstant()) - { - m_errorReporter.typeError(_identifier.location, "Constant variables not supported by inline assembly."); - return size_t(-1); - } else if (!var->isLocalVariable()) { m_errorReporter.typeError(_identifier.location, "Only local variables are supported. To access storage variables, use the _slot and _offset suffixes."); @@ -972,7 +972,11 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement) string errorText{"Uninitialized storage pointer."}; if (varDecl.referenceLocation() == VariableDeclaration::Location::Default) errorText += " Did you mean '<type> memory " + varDecl.name() + "'?"; - m_errorReporter.warning(varDecl.location(), errorText); + solAssert(m_scope, ""); + if (m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050)) + m_errorReporter.declarationError(varDecl.location(), errorText); + else + m_errorReporter.warning(varDecl.location(), errorText); } } else if (dynamic_cast<MappingType const*>(type(varDecl).get())) diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index 51249f20..cd9f7eca 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -324,6 +324,7 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node) { std::vector<pair<string, Json::Value>> attributes = { make_pair("name", _node.name()), + make_pair("documentation", _node.documentation() ? Json::Value(*_node.documentation()) : Json::nullValue), // FIXME: remove with next breaking release make_pair(m_legacy ? "constant" : "isDeclaredConst", _node.stateMutability() <= StateMutability::View), make_pair("payable", _node.isPayable()), @@ -365,6 +366,7 @@ bool ASTJsonConverter::visit(ModifierDefinition const& _node) { setJsonNode(_node, "ModifierDefinition", { make_pair("name", _node.name()), + make_pair("documentation", _node.documentation() ? Json::Value(*_node.documentation()) : Json::nullValue), make_pair("visibility", Declaration::visibilityToString(_node.visibility())), make_pair("parameters", toJson(_node.parameterList())), make_pair("body", toJson(_node.body())) @@ -386,6 +388,7 @@ bool ASTJsonConverter::visit(EventDefinition const& _node) m_inEvent = true; setJsonNode(_node, "EventDefinition", { make_pair("name", _node.name()), + make_pair("documentation", _node.documentation() ? Json::Value(*_node.documentation()) : Json::nullValue), make_pair("parameters", toJson(_node.parameterList())), make_pair("anonymous", _node.isAnonymous()) }); diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 7a88475a..0198a107 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -319,7 +319,7 @@ void CompilerContext::appendInlineAssembly( ErrorList errors; ErrorReporter errorReporter(errors); auto scanner = make_shared<Scanner>(CharStream(_assembly), "--CODEGEN--"); - auto parserResult = assembly::Parser(errorReporter, assembly::AsmFlavour::Strict).parse(scanner); + auto parserResult = assembly::Parser(errorReporter, assembly::AsmFlavour::Strict).parse(scanner, false); #ifdef SOL_OUTPUT_ASM cout << assembly::AsmPrinter()(*parserResult) << endl; #endif diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 8e1cf019..61920592 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -765,7 +765,11 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) case FunctionType::Kind::AddMod: case FunctionType::Kind::MulMod: { - for (unsigned i = 0; i < 3; i ++) + arguments[2]->accept(*this); + utils().convertType(*arguments[2]->annotation().type, IntegerType(256)); + m_context << Instruction::DUP1 << Instruction::ISZERO; + m_context.appendConditionalInvalid(); + for (unsigned i = 1; i < 3; i ++) { arguments[2 - i]->accept(*this); utils().convertType(*arguments[2 - i]->annotation().type, IntegerType(256)); diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index 2d6e58de..a05ac57d 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -82,6 +82,19 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal) ); return false; } + else if (_literal.kind == assembly::LiteralKind::Number && bigint(_literal.value) > u256(-1)) + { + m_errorReporter.typeError( + _literal.location, + "Number literal too large (> 256 bits)" + ); + return false; + } + else if (_literal.kind == assembly::LiteralKind::Boolean) + { + solAssert(m_flavour == AsmFlavour::IULIA, ""); + solAssert(_literal.value == "true" || _literal.value == "false", ""); + } m_info.stackHeightInfo[&_literal] = m_stackHeight; return true; } diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 306b07e6..7f618e07 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -34,13 +34,16 @@ using namespace dev; using namespace dev::solidity; using namespace dev::solidity::assembly; -shared_ptr<assembly::Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner) +shared_ptr<assembly::Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner) { m_recursionDepth = 0; try { m_scanner = _scanner; - return make_shared<Block>(parseBlock()); + auto block = make_shared<Block>(parseBlock()); + if (!_reuseScanner) + expectToken(Token::EOS); + return block; } catch (FatalError const&) { diff --git a/libsolidity/inlineasm/AsmParser.h b/libsolidity/inlineasm/AsmParser.h index 015aeef3..41117228 100644 --- a/libsolidity/inlineasm/AsmParser.h +++ b/libsolidity/inlineasm/AsmParser.h @@ -41,8 +41,9 @@ public: ParserBase(_errorReporter), m_flavour(_flavour) {} /// Parses an inline assembly block starting with `{` and ending with `}`. + /// @param _reuseScanner if true, do check for end of input after the `}`. /// @returns an empty shared pointer on error. - std::shared_ptr<Block> parse(std::shared_ptr<Scanner> const& _scanner); + std::shared_ptr<Block> parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner); protected: using ElementaryOperation = boost::variant<assembly::Instruction, assembly::Literal, assembly::Identifier>; diff --git a/libsolidity/interface/AssemblyStack.cpp b/libsolidity/interface/AssemblyStack.cpp index 1b4bd270..c9e534c7 100644 --- a/libsolidity/interface/AssemblyStack.cpp +++ b/libsolidity/interface/AssemblyStack.cpp @@ -69,7 +69,7 @@ bool AssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string m_errors.clear(); m_analysisSuccessful = false; m_scanner = make_shared<Scanner>(CharStream(_source), _sourceName); - m_parserResult = assembly::Parser(m_errorReporter, languageToAsmFlavour(m_language)).parse(m_scanner); + m_parserResult = assembly::Parser(m_errorReporter, languageToAsmFlavour(m_language)).parse(m_scanner, false); if (!m_errorReporter.errors().empty()) return false; solAssert(m_parserResult, ""); diff --git a/libsolidity/interface/SourceReferenceFormatter.cpp b/libsolidity/interface/SourceReferenceFormatter.cpp index aeafaf2d..9d02c498 100644 --- a/libsolidity/interface/SourceReferenceFormatter.cpp +++ b/libsolidity/interface/SourceReferenceFormatter.cpp @@ -31,15 +31,11 @@ namespace dev namespace solidity { -void SourceReferenceFormatter::printSourceLocation( - ostream& _stream, - SourceLocation const* _location, - function<Scanner const&(string const&)> const& _scannerFromSourceName -) +void SourceReferenceFormatter::printSourceLocation(SourceLocation const* _location) { if (!_location || !_location->sourceName) return; // Nothing we can print here - auto const& scanner = _scannerFromSourceName(*_location->sourceName); + auto const& scanner = m_scannerFromSourceName(*_location->sourceName); int startLine; int startColumn; tie(startLine, startColumn) = scanner.translatePositionToLineColumn(_location->start); @@ -64,21 +60,22 @@ void SourceReferenceFormatter::printSourceLocation( endColumn = startColumn + locationLength; } - _stream << line << endl; + m_stream << line << endl; + for_each( line.cbegin(), line.cbegin() + startColumn, - [&_stream](char const& ch) { _stream << (ch == '\t' ? '\t' : ' '); } + [this](char const& ch) { m_stream << (ch == '\t' ? '\t' : ' '); } ); - _stream << "^"; + m_stream << "^"; if (endColumn > startColumn + 2) - _stream << string(endColumn - startColumn - 2, '-'); + m_stream << string(endColumn - startColumn - 2, '-'); if (endColumn > startColumn + 1) - _stream << "^"; - _stream << endl; + m_stream << "^"; + m_stream << endl; } else - _stream << + m_stream << scanner.lineAtPosition(_location->start) << endl << string(startColumn, ' ') << @@ -86,50 +83,44 @@ void SourceReferenceFormatter::printSourceLocation( "Spanning multiple lines.\n"; } -void SourceReferenceFormatter::printSourceName( - ostream& _stream, - SourceLocation const* _location, - function<Scanner const&(string const&)> const& _scannerFromSourceName -) +void SourceReferenceFormatter::printSourceName(SourceLocation const* _location) { if (!_location || !_location->sourceName) return; // Nothing we can print here - auto const& scanner = _scannerFromSourceName(*_location->sourceName); + auto const& scanner = m_scannerFromSourceName(*_location->sourceName); int startLine; int startColumn; tie(startLine, startColumn) = scanner.translatePositionToLineColumn(_location->start); - _stream << *_location->sourceName << ":" << (startLine + 1) << ":" << (startColumn + 1) << ": "; + m_stream << *_location->sourceName << ":" << (startLine + 1) << ":" << (startColumn + 1) << ": "; } void SourceReferenceFormatter::printExceptionInformation( - ostream& _stream, Exception const& _exception, - string const& _name, - function<Scanner const&(string const&)> const& _scannerFromSourceName + string const& _name ) { SourceLocation const* location = boost::get_error_info<errinfo_sourceLocation>(_exception); auto secondarylocation = boost::get_error_info<errinfo_secondarySourceLocation>(_exception); - printSourceName(_stream, location, _scannerFromSourceName); + printSourceName(location); - _stream << _name; + m_stream << _name; if (string const* description = boost::get_error_info<errinfo_comment>(_exception)) - _stream << ": " << *description << endl; + m_stream << ": " << *description << endl; else - _stream << endl; + m_stream << endl; - printSourceLocation(_stream, location, _scannerFromSourceName); + printSourceLocation(location); if (secondarylocation && !secondarylocation->infos.empty()) { for (auto info: secondarylocation->infos) { - printSourceName(_stream, &info.second, _scannerFromSourceName); - _stream << info.first << endl; - printSourceLocation(_stream, &info.second, _scannerFromSourceName); + printSourceName(&info.second); + m_stream << info.first << endl; + printSourceLocation(&info.second); } - _stream << endl; + m_stream << endl; } } diff --git a/libsolidity/interface/SourceReferenceFormatter.h b/libsolidity/interface/SourceReferenceFormatter.h index e8676d60..a32babdc 100644 --- a/libsolidity/interface/SourceReferenceFormatter.h +++ b/libsolidity/interface/SourceReferenceFormatter.h @@ -38,22 +38,23 @@ namespace solidity class Scanner; // forward class CompilerStack; // forward -struct SourceReferenceFormatter +class SourceReferenceFormatter { public: using ScannerFromSourceNameFun = std::function<Scanner const&(std::string const&)>; - /// Prints source location if it is given. - static void printSourceLocation( - std::ostream& _stream, - SourceLocation const* _location, - ScannerFromSourceNameFun const& _scannerFromSourceName - ); - static void printExceptionInformation( + + explicit SourceReferenceFormatter( std::ostream& _stream, - Exception const& _exception, - std::string const& _name, - ScannerFromSourceNameFun const& _scannerFromSourceName - ); + ScannerFromSourceNameFun _scannerFromSourceName + ): + m_stream(_stream), + m_scannerFromSourceName(std::move(_scannerFromSourceName)) + {} + + /// Prints source location if it is given. + void printSourceLocation(SourceLocation const* _location); + void printExceptionInformation(Exception const& _exception, std::string const& _name); + static std::string formatExceptionInformation( Exception const& _exception, std::string const& _name, @@ -61,16 +62,17 @@ public: ) { std::ostringstream errorOutput; - printExceptionInformation(errorOutput, _exception, _name, _scannerFromSourceName); + + SourceReferenceFormatter formatter(errorOutput, _scannerFromSourceName); + formatter.printExceptionInformation(_exception, _name); return errorOutput.str(); } private: /// Prints source name if location is given. - static void printSourceName( - std::ostream& _stream, - SourceLocation const* _location, - ScannerFromSourceNameFun const& _scannerFromSourceName - ); + void printSourceName(SourceLocation const* _location); + + std::ostream& m_stream; + ScannerFromSourceNameFun m_scannerFromSourceName; }; } diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 04f5bd25..fb973d51 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -236,7 +236,11 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input) return formatFatalError("JSONError", "Only \"Solidity\" is supported as a language."); Json::Value const& sources = _input["sources"]; - if (!sources) + + if (!sources.isObject() && !sources.isNull()) + return formatFatalError("JSONError", "\"sources\" is not a JSON object."); + + if (sources.empty()) return formatFatalError("JSONError", "No input sources specified."); Json::Value errors = Json::arrayValue; @@ -550,12 +554,11 @@ Json::Value StandardCompiler::compile(Json::Value const& _input) string StandardCompiler::compile(string const& _input) { Json::Value input; - Json::Reader reader; - + string errors; try { - if (!reader.parse(_input, input, false)) - return jsonCompactPrint(formatFatalError("JSONError", reader.getFormattedErrorMessages())); + if (!jsonParseStrict(_input, input, &errors)) + return jsonCompactPrint(formatFatalError("JSONError", errors)); } catch(...) { diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 05b877b5..e306e21b 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -926,7 +926,7 @@ ASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> con } assembly::Parser asmParser(m_errorReporter); - shared_ptr<assembly::Block> block = asmParser.parse(m_scanner); + shared_ptr<assembly::Block> block = asmParser.parse(m_scanner, true); nodeFactory.markEndPosition(); return nodeFactory.createNode<InlineAssembly>(_docString, block); } |