diff options
-rw-r--r-- | circle.yml | 16 | ||||
-rw-r--r-- | docs/installing-solidity.rst | 2 | ||||
-rw-r--r-- | libjulia/optimiser/FullInliner.cpp | 4 | ||||
-rw-r--r-- | libsolidity/CMakeLists.txt | 2 | ||||
-rw-r--r-- | libsolidity/inlineasm/AsmAnalysis.cpp | 10 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.cpp | 90 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.h | 22 | ||||
-rw-r--r-- | lllc/CMakeLists.txt | 2 | ||||
-rw-r--r-- | test/tools/CMakeLists.txt | 2 |
9 files changed, 104 insertions, 46 deletions
@@ -19,8 +19,6 @@ defaults: - run_tests: &run_tests name: Tests command: scripts/tests.sh --junit_report test_results - environment: - TERM: dumb - solc_artifact: &solc_artifact path: build/solc/solc destination: solc @@ -36,6 +34,8 @@ jobs: build_emscripten: docker: - image: trzeci/emscripten:sdk-tag-1.37.21-64bit + environment: + TERM: xterm steps: - checkout - restore_cache: @@ -68,6 +68,8 @@ jobs: test_emscripten_solcjs: docker: - image: trzeci/emscripten:sdk-tag-1.37.21-64bit + environment: + TERM: xterm steps: - checkout - attach_workspace: @@ -92,6 +94,8 @@ jobs: test_emscripten_external: docker: - image: trzeci/emscripten:sdk-tag-1.37.21-64bit + environment: + TERM: xterm steps: - checkout - attach_workspace: @@ -116,6 +120,8 @@ jobs: build_x86_linux: docker: - image: buildpack-deps:artful + environment: + TERM: xterm steps: - checkout - run: @@ -131,6 +137,8 @@ jobs: build_x86_mac: macos: xcode: "9.0" + environment: + TERM: xterm steps: - checkout - run: @@ -150,6 +158,8 @@ jobs: test_x86_linux: docker: - image: buildpack-deps:artful + environment: + TERM: xterm steps: - checkout - attach_workspace: @@ -167,6 +177,8 @@ jobs: test_x86_mac: macos: xcode: "9.0" + environment: + TERM: xterm steps: - checkout - attach_workspace: diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index cba30ed3..05ee0748 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -35,7 +35,7 @@ npm / Node.js ============= Use `npm` for a convenient and portable way to install `solcjs`, a Solidity compiler. The -`solcjs` program has less features than all options further down this page. Our +`solcjs` program has fewer features than all options further down this page. Our :ref:`commandline-compiler` documentation assumes you are using the full-featured compiler, `solc`. So if you install `solcjs` from `npm` then you will stop reading the documentation here and then continue to `solc-js <https://github.com/ethereum/solc-js>`_. diff --git a/libjulia/optimiser/FullInliner.cpp b/libjulia/optimiser/FullInliner.cpp index e78f4eb0..e8776e23 100644 --- a/libjulia/optimiser/FullInliner.cpp +++ b/libjulia/optimiser/FullInliner.cpp @@ -168,10 +168,10 @@ void InlineModifier::visit(Statement& _statement) // Replace pop(0) expression statemets (and others) by empty blocks. if (_statement.type() == typeid(ExpressionStatement)) { - ExpressionStatement& expSt = boost::get<ExpressionStatement&>(_statement); + ExpressionStatement& expSt = boost::get<ExpressionStatement>(_statement); if (expSt.expression.type() == typeid(FunctionalInstruction)) { - FunctionalInstruction& funInstr = boost::get<FunctionalInstruction&>(expSt.expression); + FunctionalInstruction& funInstr = boost::get<FunctionalInstruction>(expSt.expression); if (funInstr.instruction == solidity::Instruction::POP) if (MovableChecker(funInstr.arguments.at(0)).movable()) _statement = Block{expSt.location, {}}; diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt index 97b01c83..0bdec4b4 100644 --- a/libsolidity/CMakeLists.txt +++ b/libsolidity/CMakeLists.txt @@ -28,7 +28,7 @@ else() endif() add_library(solidity ${sources} ${headers}) -target_link_libraries(solidity PUBLIC evmasm devcore) +target_link_libraries(solidity PUBLIC evmasm devcore ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY}) if (${Z3_FOUND}) target_link_libraries(solidity PUBLIC ${Z3_LIBRARY}) diff --git a/libsolidity/inlineasm/AsmAnalysis.cpp b/libsolidity/inlineasm/AsmAnalysis.cpp index abf7ddf2..9f505889 100644 --- a/libsolidity/inlineasm/AsmAnalysis.cpp +++ b/libsolidity/inlineasm/AsmAnalysis.cpp @@ -54,6 +54,7 @@ bool AsmAnalyzer::analyze(Block const& _block) bool AsmAnalyzer::operator()(Label const& _label) { + solAssert(!_label.name.empty(), ""); checkLooseFeature( _label.location, "The use of labels is deprecated. Please use \"if\", \"switch\", \"for\" or function calls instead." @@ -107,6 +108,7 @@ bool AsmAnalyzer::operator()(assembly::Literal const& _literal) bool AsmAnalyzer::operator()(assembly::Identifier const& _identifier) { + solAssert(!_identifier.name.empty(), ""); size_t numErrorsBefore = m_errorReporter.errors().size(); bool success = true; if (m_currentScope->lookup(_identifier.name, Scope::Visitor( @@ -208,6 +210,7 @@ bool AsmAnalyzer::operator()(assembly::StackAssignment const& _assignment) bool AsmAnalyzer::operator()(assembly::Assignment const& _assignment) { + solAssert(_assignment.value, ""); int const expectedItems = _assignment.variableNames.size(); solAssert(expectedItems >= 1, ""); int const stackHeight = m_stackHeight; @@ -259,6 +262,7 @@ bool AsmAnalyzer::operator()(assembly::VariableDeclaration const& _varDecl) bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef) { + solAssert(!_funDef.name.empty(), ""); Block const* virtualBlock = m_info.virtualBlocks.at(&_funDef).get(); solAssert(virtualBlock, ""); Scope& varScope = scope(virtualBlock); @@ -280,6 +284,7 @@ bool AsmAnalyzer::operator()(assembly::FunctionDefinition const& _funDef) bool AsmAnalyzer::operator()(assembly::FunctionCall const& _funCall) { + solAssert(!_funCall.functionName.name.empty(), ""); bool success = true; size_t arguments = 0; size_t returns = 0; @@ -349,6 +354,8 @@ bool AsmAnalyzer::operator()(If const& _if) bool AsmAnalyzer::operator()(Switch const& _switch) { + solAssert(_switch.expression, ""); + bool success = true; if (!expectExpression(*_switch.expression)) @@ -391,6 +398,8 @@ bool AsmAnalyzer::operator()(Switch const& _switch) bool AsmAnalyzer::operator()(assembly::ForLoop const& _for) { + solAssert(_for.condition, ""); + Scope* originalScope = m_currentScope; bool success = true; @@ -478,6 +487,7 @@ bool AsmAnalyzer::expectDeposit(int _deposit, int _oldHeight, SourceLocation con bool AsmAnalyzer::checkAssignment(assembly::Identifier const& _variable, size_t _valueSize) { + solAssert(!_variable.name.empty(), ""); bool success = true; size_t numErrorsBefore = m_errorReporter.errors().size(); size_t variableSize(-1); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 49745e29..d1be13a5 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1083,18 +1083,46 @@ ASTPointer<EmitStatement> Parser::parseEmitStatement(ASTPointer<ASTString> const ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& _docString) { RecursionGuard recursionGuard(*this); + LookAheadInfo statementType; + IndexAccessedPath iap; + + tie(statementType, iap) = tryParseIndexAccessedPath(); + switch (statementType) + { + case LookAheadInfo::VariableDeclaration: + return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap)); + case LookAheadInfo::Expression: + return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap)); + default: + solAssert(false, ""); + } +} + +bool Parser::IndexAccessedPath::empty() const +{ + if (!indices.empty()) + { + solAssert(!path.empty(), ""); + } + return path.empty() && indices.empty(); +} + + +pair<Parser::LookAheadInfo, Parser::IndexAccessedPath> Parser::tryParseIndexAccessedPath() +{ // These two cases are very hard to distinguish: - // x[7 * 20 + 3] a; - x[7 * 20 + 3] = 9; + // x[7 * 20 + 3] a; and x[7 * 20 + 3] = 9; // In the first case, x is a type name, in the second it is the name of a variable. // As an extension, we can even have: // `x.y.z[1][2] a;` and `x.y.z[1][2] = 10;` // Where in the first, x.y.z leads to a type name where in the second, it accesses structs. - switch (peekStatementType()) + + auto statementType = peekStatementType(); + switch (statementType) { - case LookAheadInfo::VariableDeclarationStatement: - return parseVariableDeclarationStatement(_docString); - case LookAheadInfo::ExpressionStatement: - return parseExpressionStatement(_docString); + case LookAheadInfo::VariableDeclaration: + case LookAheadInfo::Expression: + return make_pair(statementType, IndexAccessedPath()); default: break; } @@ -1106,9 +1134,9 @@ ASTPointer<Statement> Parser::parseSimpleStatement(ASTPointer<ASTString> const& IndexAccessedPath iap = parseIndexAccessedPath(); if (m_scanner->currentToken() == Token::Identifier || Token::isLocationSpecifier(m_scanner->currentToken())) - return parseVariableDeclarationStatement(_docString, typeNameFromIndexAccessStructure(iap)); + return make_pair(LookAheadInfo::VariableDeclaration, move(iap)); else - return parseExpressionStatement(_docString, expressionFromIndexAccessStructure(iap)); + return make_pair(LookAheadInfo::Expression, move(iap)); } ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement( @@ -1178,20 +1206,20 @@ ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStateme ASTPointer<ExpressionStatement> Parser::parseExpressionStatement( ASTPointer<ASTString> const& _docString, - ASTPointer<Expression> const& _lookAheadIndexAccessStructure + ASTPointer<Expression> const& _partialParserResult ) { RecursionGuard recursionGuard(*this); - ASTPointer<Expression> expression = parseExpression(_lookAheadIndexAccessStructure); + ASTPointer<Expression> expression = parseExpression(_partialParserResult); return ASTNodeFactory(*this, expression).createNode<ExpressionStatement>(_docString, expression); } ASTPointer<Expression> Parser::parseExpression( - ASTPointer<Expression> const& _lookAheadIndexAccessStructure + ASTPointer<Expression> const& _partiallyParsedExpression ) { RecursionGuard recursionGuard(*this); - ASTPointer<Expression> expression = parseBinaryExpression(4, _lookAheadIndexAccessStructure); + ASTPointer<Expression> expression = parseBinaryExpression(4, _partiallyParsedExpression); if (Token::isAssignmentOp(m_scanner->currentToken())) { Token::Value assignmentOperator = m_scanner->currentToken(); @@ -1217,11 +1245,11 @@ ASTPointer<Expression> Parser::parseExpression( ASTPointer<Expression> Parser::parseBinaryExpression( int _minPrecedence, - ASTPointer<Expression> const& _lookAheadIndexAccessStructure + ASTPointer<Expression> const& _partiallyParsedExpression ) { RecursionGuard recursionGuard(*this); - ASTPointer<Expression> expression = parseUnaryExpression(_lookAheadIndexAccessStructure); + ASTPointer<Expression> expression = parseUnaryExpression(_partiallyParsedExpression); ASTNodeFactory nodeFactory(*this, expression); int precedence = Token::precedence(m_scanner->currentToken()); for (; precedence >= _minPrecedence; --precedence) @@ -1237,14 +1265,14 @@ ASTPointer<Expression> Parser::parseBinaryExpression( } ASTPointer<Expression> Parser::parseUnaryExpression( - ASTPointer<Expression> const& _lookAheadIndexAccessStructure + ASTPointer<Expression> const& _partiallyParsedExpression ) { RecursionGuard recursionGuard(*this); - ASTNodeFactory nodeFactory = _lookAheadIndexAccessStructure ? - ASTNodeFactory(*this, _lookAheadIndexAccessStructure) : ASTNodeFactory(*this); + ASTNodeFactory nodeFactory = _partiallyParsedExpression ? + ASTNodeFactory(*this, _partiallyParsedExpression) : ASTNodeFactory(*this); Token::Value token = m_scanner->currentToken(); - if (!_lookAheadIndexAccessStructure && (Token::isUnaryOp(token) || Token::isCountOp(token))) + if (!_partiallyParsedExpression && (Token::isUnaryOp(token) || Token::isCountOp(token))) { // prefix expression m_scanner->next(); @@ -1255,7 +1283,7 @@ ASTPointer<Expression> Parser::parseUnaryExpression( else { // potential postfix expression - ASTPointer<Expression> subExpression = parseLeftHandSideExpression(_lookAheadIndexAccessStructure); + ASTPointer<Expression> subExpression = parseLeftHandSideExpression(_partiallyParsedExpression); token = m_scanner->currentToken(); if (!Token::isCountOp(token)) return subExpression; @@ -1266,16 +1294,16 @@ ASTPointer<Expression> Parser::parseUnaryExpression( } ASTPointer<Expression> Parser::parseLeftHandSideExpression( - ASTPointer<Expression> const& _lookAheadIndexAccessStructure + ASTPointer<Expression> const& _partiallyParsedExpression ) { RecursionGuard recursionGuard(*this); - ASTNodeFactory nodeFactory = _lookAheadIndexAccessStructure ? - ASTNodeFactory(*this, _lookAheadIndexAccessStructure) : ASTNodeFactory(*this); + ASTNodeFactory nodeFactory = _partiallyParsedExpression ? + ASTNodeFactory(*this, _partiallyParsedExpression) : ASTNodeFactory(*this); ASTPointer<Expression> expression; - if (_lookAheadIndexAccessStructure) - expression = _lookAheadIndexAccessStructure; + if (_partiallyParsedExpression) + expression = _partiallyParsedExpression; else if (m_scanner->currentToken() == Token::New) { expectToken(Token::New); @@ -1489,16 +1517,16 @@ Parser::LookAheadInfo Parser::peekStatementType() const bool mightBeTypeName = (Token::isElementaryTypeName(token) || token == Token::Identifier); if (token == Token::Mapping || token == Token::Function || token == Token::Var) - return LookAheadInfo::VariableDeclarationStatement; + return LookAheadInfo::VariableDeclaration; if (mightBeTypeName) { Token::Value next = m_scanner->peekNextToken(); if (next == Token::Identifier || Token::isLocationSpecifier(next)) - return LookAheadInfo::VariableDeclarationStatement; + return LookAheadInfo::VariableDeclaration; if (next == Token::LBrack || next == Token::Period) return LookAheadInfo::IndexAccessStructure; } - return LookAheadInfo::ExpressionStatement; + return LookAheadInfo::Expression; } Parser::IndexAccessedPath Parser::parseIndexAccessedPath() @@ -1539,7 +1567,9 @@ Parser::IndexAccessedPath Parser::parseIndexAccessedPath() ASTPointer<TypeName> Parser::typeNameFromIndexAccessStructure(Parser::IndexAccessedPath const& _iap) { - solAssert(!_iap.path.empty(), ""); + if (_iap.empty()) + return {}; + RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this); SourceLocation location = _iap.path.front()->location(); @@ -1571,7 +1601,9 @@ ASTPointer<Expression> Parser::expressionFromIndexAccessStructure( Parser::IndexAccessedPath const& _iap ) { - solAssert(!_iap.path.empty(), ""); + if (_iap.empty()) + return {}; + RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this, _iap.path.front()); ASTPointer<Expression> expression(_iap.path.front()); diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 7f02d895..08653364 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -118,19 +118,19 @@ private: ); ASTPointer<ExpressionStatement> parseExpressionStatement( ASTPointer<ASTString> const& _docString, - ASTPointer<Expression> const& _lookAheadIndexAccessStructure = ASTPointer<Expression>() + ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>() ); ASTPointer<Expression> parseExpression( - ASTPointer<Expression> const& _lookAheadIndexAccessStructure = ASTPointer<Expression>() + ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>() ); ASTPointer<Expression> parseBinaryExpression(int _minPrecedence = 4, - ASTPointer<Expression> const& _lookAheadIndexAccessStructure = ASTPointer<Expression>() + ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>() ); ASTPointer<Expression> parseUnaryExpression( - ASTPointer<Expression> const& _lookAheadIndexAccessStructure = ASTPointer<Expression>() + ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>() ); ASTPointer<Expression> parseLeftHandSideExpression( - ASTPointer<Expression> const& _lookAheadIndexAccessStructure = ASTPointer<Expression>() + ASTPointer<Expression> const& _partiallyParsedExpression = ASTPointer<Expression>() ); ASTPointer<Expression> parsePrimaryExpression(); std::vector<ASTPointer<Expression>> parseFunctionCallListArguments(); @@ -143,16 +143,18 @@ private: /// Used as return value of @see peekStatementType. enum class LookAheadInfo { - IndexAccessStructure, VariableDeclarationStatement, ExpressionStatement + IndexAccessStructure, VariableDeclaration, Expression }; /// Structure that represents a.b.c[x][y][z]. Can be converted either to an expression - /// or to a type name. Path cannot be empty, but indices can be empty. + /// or to a type name. For this to be valid, path cannot be empty, but indices can be empty. struct IndexAccessedPath { std::vector<ASTPointer<PrimaryExpression>> path; std::vector<std::pair<ASTPointer<Expression>, SourceLocation>> indices; + bool empty() const; }; + std::pair<LookAheadInfo, IndexAccessedPath> tryParseIndexAccessedPath(); /// Performs limited look-ahead to distinguish between variable declaration and expression statement. /// For source code of the form "a[][8]" ("IndexAccessStructure"), this is not possible to /// decide with constant look-ahead. @@ -160,9 +162,11 @@ private: /// @returns an IndexAccessedPath as a prestage to parsing a variable declaration (type name) /// or an expression; IndexAccessedPath parseIndexAccessedPath(); - /// @returns a typename parsed in look-ahead fashion from something like "a.b[8][2**70]". + /// @returns a typename parsed in look-ahead fashion from something like "a.b[8][2**70]", + /// or an empty pointer if an empty @a _pathAndIncides has been supplied. ASTPointer<TypeName> typeNameFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices); - /// @returns an expression parsed in look-ahead fashion from something like "a.b[8][2**70]". + /// @returns an expression parsed in look-ahead fashion from something like "a.b[8][2**70]", + /// or an empty pointer if an empty @a _pathAndIncides has been supplied. ASTPointer<Expression> expressionFromIndexAccessStructure(IndexAccessedPath const& _pathAndIndices); ASTPointer<ASTString> expectIdentifierToken(); diff --git a/lllc/CMakeLists.txt b/lllc/CMakeLists.txt index 5c480093..d6538ee2 100644 --- a/lllc/CMakeLists.txt +++ b/lllc/CMakeLists.txt @@ -1,5 +1,5 @@ add_executable(lllc main.cpp) -target_link_libraries(lllc PRIVATE lll) +target_link_libraries(lllc PRIVATE lll ${Boost_SYSTEM_LIBRARY}) if (INSTALL_LLLC) include(GNUInstallDirs) diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt index febb0c26..11714017 100644 --- a/test/tools/CMakeLists.txt +++ b/test/tools/CMakeLists.txt @@ -1,5 +1,5 @@ add_executable(solfuzzer fuzzer.cpp) -target_link_libraries(solfuzzer PRIVATE libsolc evmasm ${Boost_PROGRAM_OPTIONS_LIBRARIES}) +target_link_libraries(solfuzzer PRIVATE libsolc evmasm ${Boost_PROGRAM_OPTIONS_LIBRARIES} ${Boost_SYSTEM_LIBRARIES}) add_executable(isoltest isoltest.cpp ../Options.cpp ../libsolidity/SyntaxTest.cpp ../libsolidity/AnalysisFramework.cpp) target_link_libraries(isoltest PRIVATE libsolc solidity evmasm ${Boost_PROGRAM_OPTIONS_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) |