aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--circle.yml16
-rw-r--r--docs/installing-solidity.rst2
-rw-r--r--libjulia/optimiser/FullInliner.cpp4
-rw-r--r--libsolidity/CMakeLists.txt2
-rw-r--r--libsolidity/inlineasm/AsmAnalysis.cpp10
-rw-r--r--libsolidity/parsing/Parser.cpp90
-rw-r--r--libsolidity/parsing/Parser.h22
-rw-r--r--lllc/CMakeLists.txt2
-rw-r--r--test/tools/CMakeLists.txt2
9 files changed, 104 insertions, 46 deletions
diff --git a/circle.yml b/circle.yml
index e29f3e4a..4ce3082b 100644
--- a/circle.yml
+++ b/circle.yml
@@ -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})