aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--libjulia/Exceptions.h35
-rw-r--r--libjulia/optimiser/ASTCopier.cpp11
-rw-r--r--libjulia/optimiser/ASTWalker.cpp2
-rw-r--r--libjulia/optimiser/ASTWalker.h14
-rw-r--r--libjulia/optimiser/CommonSubexpressionEliminator.cpp3
-rw-r--r--libjulia/optimiser/DataFlowAnalyzer.cpp8
-rw-r--r--libjulia/optimiser/Disambiguator.cpp12
-rw-r--r--libjulia/optimiser/ExpressionInliner.h2
-rw-r--r--libjulia/optimiser/ExpressionSimplifier.cpp2
-rw-r--r--libjulia/optimiser/FullInliner.cpp17
-rw-r--r--libjulia/optimiser/FullInliner.h5
-rw-r--r--libjulia/optimiser/FunctionGrouper.cpp2
-rw-r--r--libjulia/optimiser/FunctionHoister.cpp2
-rw-r--r--libjulia/optimiser/InlinableExpressionFunctionFinder.cpp6
-rw-r--r--libjulia/optimiser/InlinableExpressionFunctionFinder.h2
-rw-r--r--libjulia/optimiser/MainFunction.cpp54
-rw-r--r--libjulia/optimiser/MainFunction.h41
-rw-r--r--libjulia/optimiser/README.md9
-rw-r--r--libjulia/optimiser/Rematerialiser.cpp3
-rw-r--r--libjulia/optimiser/Semantics.cpp4
-rw-r--r--libjulia/optimiser/SyntacticalEquality.cpp5
-rw-r--r--libjulia/optimiser/UnusedPruner.cpp5
-rw-r--r--libjulia/optimiser/Utilities.h5
-rw-r--r--libsolidity/parsing/ParserBase.cpp4
-rw-r--r--test/libjulia/MainFunction.cpp87
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp157
-rw-r--r--test/libsolidity/StandardCompiler.cpp2
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/constant_is_keyword.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/emit_without_event.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/empty_enum.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/event_with_no_argument_list.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/external_variable.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/fixed_literal_with_double_radix.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable_with_modifiers.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_lvalue.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_without_lvalue.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/local_const_variable.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/location_specifiers_for_state_variables.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/location_specifiers_with_var.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/malformed_enum_declaration.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/missing_argument_in_named_args.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/missing_parameter_name_in_named_args.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/modifier_without_semicolon.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/new_invalid_type_name.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/payable_accessor.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/return_var.sol28
-rw-r--r--test/libsolidity/syntaxTests/parsing/single_function_param_trailing_comma.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/single_return_param_trailing_comma.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/trailing_comma_in_named_args.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/tuples_without_commas.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/var_array.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol28
-rw-r--r--test/libsolidity/syntaxTests/parsing/var_storage_var.sol2
-rw-r--r--test/libsolidity/syntaxTests/parsing/variable_definition_in_mapping.sol2
58 files changed, 491 insertions, 121 deletions
diff --git a/Changelog.md b/Changelog.md
index a87c8dd4..9004dc29 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -6,6 +6,7 @@ Features:
* Gas Estimator: Only explore paths with higher gas costs. This reduces accuracy but greatly improves the speed of gas estimation.
* Optimizer: Remove unnecessary masking of the result of known short instructions (``ADDRESS``, ``CALLER``, ``ORIGIN`` and ``COINBASE``).
* Parser: Display nicer error messages by showing the actual tokens and not internal names.
+ * Parser: Use the entire location of the token instead of only its starting position as source location for parser errors.
* Type Checker: Deprecate the ``years`` unit denomination and raise a warning for it (or an error as experimental 0.5.0 feature).
* Type Checker: Make literals (without explicit type casting) an error for tight packing as experimental 0.5.0 feature.
* Type Checker: Warn about wildcard tuple assignments (this will turn into an error with version 0.5.0).
diff --git a/libjulia/Exceptions.h b/libjulia/Exceptions.h
new file mode 100644
index 00000000..20ab6520
--- /dev/null
+++ b/libjulia/Exceptions.h
@@ -0,0 +1,35 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * Exceptions in Julia.
+ */
+
+#pragma once
+
+#include <libdevcore/Exceptions.h>
+#include <libdevcore/Assertions.h>
+
+namespace dev
+{
+namespace julia
+{
+
+struct IuliaException: virtual Exception {};
+struct OptimizerException: virtual IuliaException {};
+
+}
+}
diff --git a/libjulia/optimiser/ASTCopier.cpp b/libjulia/optimiser/ASTCopier.cpp
index 5c47be64..a8a1e30f 100644
--- a/libjulia/optimiser/ASTCopier.cpp
+++ b/libjulia/optimiser/ASTCopier.cpp
@@ -20,9 +20,9 @@
#include <libjulia/optimiser/ASTCopier.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libjulia/Exceptions.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <libsolidity/inlineasm/AsmData.h>
#include <libdevcore/Common.h>
@@ -30,10 +30,9 @@ using namespace std;
using namespace dev;
using namespace dev::julia;
-
Statement ASTCopier::operator()(Instruction const&)
{
- solAssert(false, "Invalid operation.");
+ assertThrow(false, OptimizerException, "Invalid operation.");
return {};
}
@@ -62,13 +61,13 @@ Statement ASTCopier::operator()(Assignment const& _assignment)
Statement ASTCopier::operator()(StackAssignment const&)
{
- solAssert(false, "Invalid operation.");
+ assertThrow(false, OptimizerException, "Invalid operation.");
return {};
}
Statement ASTCopier::operator()(Label const&)
{
- solAssert(false, "Invalid operation.");
+ assertThrow(false, OptimizerException, "Invalid operation.");
return {};
}
diff --git a/libjulia/optimiser/ASTWalker.cpp b/libjulia/optimiser/ASTWalker.cpp
index 03444984..dc94cc60 100644
--- a/libjulia/optimiser/ASTWalker.cpp
+++ b/libjulia/optimiser/ASTWalker.cpp
@@ -22,8 +22,6 @@
#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/Exceptions.h>
-
#include <boost/range/adaptor/reversed.hpp>
using namespace std;
diff --git a/libjulia/optimiser/ASTWalker.h b/libjulia/optimiser/ASTWalker.h
index f09c2ff1..e1f0f5bd 100644
--- a/libjulia/optimiser/ASTWalker.h
+++ b/libjulia/optimiser/ASTWalker.h
@@ -22,7 +22,7 @@
#include <libjulia/ASTDataForward.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <libjulia/Exceptions.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
@@ -44,13 +44,13 @@ class ASTWalker: public boost::static_visitor<>
public:
virtual ~ASTWalker() = default;
virtual void operator()(Literal const&) {}
- virtual void operator()(Instruction const&) { solAssert(false, ""); }
+ virtual void operator()(Instruction const&) { assertThrow(false, OptimizerException, ""); }
virtual void operator()(Identifier const&) {}
virtual void operator()(FunctionalInstruction const& _instr);
virtual void operator()(FunctionCall const& _funCall);
virtual void operator()(ExpressionStatement const& _statement);
- virtual void operator()(Label const&) { solAssert(false, ""); }
- virtual void operator()(StackAssignment const&) { solAssert(false, ""); }
+ virtual void operator()(Label const&) { assertThrow(false, OptimizerException, ""); }
+ virtual void operator()(StackAssignment const&) { assertThrow(false, OptimizerException, ""); }
virtual void operator()(Assignment const& _assignment);
virtual void operator()(VariableDeclaration const& _varDecl);
virtual void operator()(If const& _if);
@@ -85,13 +85,13 @@ class ASTModifier: public boost::static_visitor<>
public:
virtual ~ASTModifier() = default;
virtual void operator()(Literal&) {}
- virtual void operator()(Instruction&) { solAssert(false, ""); }
+ virtual void operator()(Instruction&) { assertThrow(false, OptimizerException, ""); }
virtual void operator()(Identifier&) {}
virtual void operator()(FunctionalInstruction& _instr);
virtual void operator()(FunctionCall& _funCall);
virtual void operator()(ExpressionStatement& _statement);
- virtual void operator()(Label&) { solAssert(false, ""); }
- virtual void operator()(StackAssignment&) { solAssert(false, ""); }
+ virtual void operator()(Label&) { assertThrow(false, OptimizerException, ""); }
+ virtual void operator()(StackAssignment&) { assertThrow(false, OptimizerException, ""); }
virtual void operator()(Assignment& _assignment);
virtual void operator()(VariableDeclaration& _varDecl);
virtual void operator()(If& _if);
diff --git a/libjulia/optimiser/CommonSubexpressionEliminator.cpp b/libjulia/optimiser/CommonSubexpressionEliminator.cpp
index 229bd35e..3122280b 100644
--- a/libjulia/optimiser/CommonSubexpressionEliminator.cpp
+++ b/libjulia/optimiser/CommonSubexpressionEliminator.cpp
@@ -23,6 +23,7 @@
#include <libjulia/optimiser/Metrics.h>
#include <libjulia/optimiser/SyntacticalEquality.h>
+#include <libjulia/Exceptions.h>
#include <libsolidity/inlineasm/AsmData.h>
@@ -37,7 +38,7 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
// TODO this search rather inefficient.
for (auto const& var: m_value)
{
- solAssert(var.second, "");
+ assertThrow(var.second, OptimizerException, "");
if (SyntacticalEqualityChecker::equal(_e, *var.second))
{
_e = Identifier{locationOf(_e), var.first};
diff --git a/libjulia/optimiser/DataFlowAnalyzer.cpp b/libjulia/optimiser/DataFlowAnalyzer.cpp
index 56653393..25f0ffb4 100644
--- a/libjulia/optimiser/DataFlowAnalyzer.cpp
+++ b/libjulia/optimiser/DataFlowAnalyzer.cpp
@@ -23,11 +23,11 @@
#include <libjulia/optimiser/DataFlowAnalyzer.h>
#include <libjulia/optimiser/NameCollector.h>
+#include <libjulia/optimiser/Semantics.h>
+#include <libjulia/Exceptions.h>
#include <libsolidity/inlineasm/AsmData.h>
-#include <libjulia/optimiser/Semantics.h>
-
#include <libdevcore/CommonData.h>
#include <boost/range/adaptor/reversed.hpp>
@@ -41,7 +41,7 @@ void DataFlowAnalyzer::operator()(Assignment& _assignment)
set<string> names;
for (auto const& var: _assignment.variableNames)
names.insert(var.name);
- solAssert(_assignment.value, "");
+ assertThrow(_assignment.value, OptimizerException, "");
visit(*_assignment.value);
handleAssignment(names, _assignment.value.get());
}
@@ -120,7 +120,7 @@ void DataFlowAnalyzer::operator()(Block& _block)
m_variableScopes.emplace_back(false);
ASTModifier::operator()(_block);
m_variableScopes.pop_back();
- solAssert(numScopes == m_variableScopes.size(), "");
+ assertThrow(numScopes == m_variableScopes.size(), OptimizerException, "");
}
void DataFlowAnalyzer::handleAssignment(set<string> const& _variables, Expression* _value)
diff --git a/libjulia/optimiser/Disambiguator.cpp b/libjulia/optimiser/Disambiguator.cpp
index b988dba7..687be9b9 100644
--- a/libjulia/optimiser/Disambiguator.cpp
+++ b/libjulia/optimiser/Disambiguator.cpp
@@ -20,11 +20,11 @@
#include <libjulia/optimiser/Disambiguator.h>
+#include <libjulia/Exceptions.h>
+
#include <libsolidity/inlineasm/AsmData.h>
#include <libsolidity/inlineasm/AsmScope.h>
-#include <libsolidity/interface/Exceptions.h>
-
using namespace std;
using namespace dev;
using namespace dev::julia;
@@ -34,9 +34,9 @@ using Scope = dev::solidity::assembly::Scope;
string Disambiguator::translateIdentifier(string const& _originalName)
{
- solAssert(!m_scopes.empty() && m_scopes.back(), "");
+ assertThrow(!m_scopes.empty() && m_scopes.back(), OptimizerException, "");
Scope::Identifier const* id = m_scopes.back()->lookup(_originalName);
- solAssert(id, "");
+ assertThrow(id, OptimizerException, "");
if (!m_translations.count(id))
m_translations[id] = m_nameDispenser.newName(_originalName);
return m_translations.at(id);
@@ -69,7 +69,7 @@ void Disambiguator::enterScopeInternal(Scope& _scope)
void Disambiguator::leaveScopeInternal(Scope& _scope)
{
- solAssert(!m_scopes.empty(), "");
- solAssert(m_scopes.back() == &_scope, "");
+ assertThrow(!m_scopes.empty(), OptimizerException, "");
+ assertThrow(m_scopes.back() == &_scope, OptimizerException, "");
m_scopes.pop_back();
}
diff --git a/libjulia/optimiser/ExpressionInliner.h b/libjulia/optimiser/ExpressionInliner.h
index 10d7659c..3d24ef5d 100644
--- a/libjulia/optimiser/ExpressionInliner.h
+++ b/libjulia/optimiser/ExpressionInliner.h
@@ -23,8 +23,6 @@
#include <libjulia/ASTDataForward.h>
-#include <libsolidity/interface/Exceptions.h>
-
#include <boost/variant.hpp>
#include <boost/optional.hpp>
diff --git a/libjulia/optimiser/ExpressionSimplifier.cpp b/libjulia/optimiser/ExpressionSimplifier.cpp
index 3d471cb3..8bd6b1c7 100644
--- a/libjulia/optimiser/ExpressionSimplifier.cpp
+++ b/libjulia/optimiser/ExpressionSimplifier.cpp
@@ -25,8 +25,6 @@
#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/Exceptions.h>
-
#include <libdevcore/CommonData.h>
using namespace std;
diff --git a/libjulia/optimiser/FullInliner.cpp b/libjulia/optimiser/FullInliner.cpp
index 05d70729..e78f4eb0 100644
--- a/libjulia/optimiser/FullInliner.cpp
+++ b/libjulia/optimiser/FullInliner.cpp
@@ -24,11 +24,10 @@
#include <libjulia/optimiser/ASTWalker.h>
#include <libjulia/optimiser/NameCollector.h>
#include <libjulia/optimiser/Semantics.h>
+#include <libjulia/Exceptions.h>
#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/Exceptions.h>
-
#include <libdevcore/CommonData.h>
#include <boost/range/adaptor/reversed.hpp>
@@ -38,18 +37,16 @@ using namespace dev;
using namespace dev::julia;
using namespace dev::solidity;
-
-
FullInliner::FullInliner(Block& _ast):
m_ast(_ast)
{
- solAssert(m_ast.statements.size() >= 1, "");
- solAssert(m_ast.statements.front().type() == typeid(Block), "");
+ assertThrow(m_ast.statements.size() >= 1, OptimizerException, "");
+ assertThrow(m_ast.statements.front().type() == typeid(Block), OptimizerException, "");
m_nameDispenser.m_usedNames = NameCollector(m_ast).names();
for (size_t i = 1; i < m_ast.statements.size(); ++i)
{
- solAssert(m_ast.statements.at(i).type() == typeid(FunctionDefinition), "");
+ assertThrow(m_ast.statements.at(i).type() == typeid(FunctionDefinition), OptimizerException, "");
FunctionDefinition& fun = boost::get<FunctionDefinition>(m_ast.statements.at(i));
m_functions[fun.name] = &fun;
m_functionsToVisit.insert(&fun);
@@ -58,7 +55,7 @@ FullInliner::FullInliner(Block& _ast):
void FullInliner::run()
{
- solAssert(m_ast.statements[0].type() == typeid(Block), "");
+ assertThrow(m_ast.statements[0].type() == typeid(Block), OptimizerException, "");
InlineModifier(*this, m_nameDispenser, "").visit(m_ast.statements[0]);
while (!m_functionsToVisit.empty())
handleFunction(**m_functionsToVisit.begin());
@@ -79,7 +76,7 @@ void InlineModifier::operator()(FunctionalInstruction& _instruction)
void InlineModifier::operator()(FunctionCall&)
{
- solAssert(false, "Should be handled in visit() instead.");
+ assertThrow(false, OptimizerException, "Should be handled in visit() instead.");
}
void InlineModifier::operator()(ForLoop& _loop)
@@ -249,7 +246,7 @@ Statement BodyCopier::operator()(VariableDeclaration const& _varDecl)
Statement BodyCopier::operator()(FunctionDefinition const& _funDef)
{
- solAssert(false, "Function hoisting has to be done before function inlining.");
+ assertThrow(false, OptimizerException, "Function hoisting has to be done before function inlining.");
return _funDef;
}
diff --git a/libjulia/optimiser/FullInliner.h b/libjulia/optimiser/FullInliner.h
index d3628e1a..ff9e6854 100644
--- a/libjulia/optimiser/FullInliner.h
+++ b/libjulia/optimiser/FullInliner.h
@@ -24,8 +24,9 @@
#include <libjulia/optimiser/ASTCopier.h>
#include <libjulia/optimiser/ASTWalker.h>
#include <libjulia/optimiser/NameDispenser.h>
+#include <libjulia/Exceptions.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <libevmasm/SourceLocation.h>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
@@ -100,7 +101,7 @@ public:
{ }
~InlineModifier()
{
- solAssert(m_statementsToPrefix.empty(), "");
+ assertThrow(m_statementsToPrefix.empty(), OptimizerException, "");
}
virtual void operator()(FunctionalInstruction&) override;
diff --git a/libjulia/optimiser/FunctionGrouper.cpp b/libjulia/optimiser/FunctionGrouper.cpp
index cc40bc46..f1e99e6b 100644
--- a/libjulia/optimiser/FunctionGrouper.cpp
+++ b/libjulia/optimiser/FunctionGrouper.cpp
@@ -23,8 +23,6 @@
#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/Exceptions.h>
-
#include <boost/range/algorithm_ext/erase.hpp>
using namespace std;
diff --git a/libjulia/optimiser/FunctionHoister.cpp b/libjulia/optimiser/FunctionHoister.cpp
index 63f6edb9..98fc714c 100644
--- a/libjulia/optimiser/FunctionHoister.cpp
+++ b/libjulia/optimiser/FunctionHoister.cpp
@@ -25,8 +25,6 @@
#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/Exceptions.h>
-
#include <libdevcore/CommonData.h>
using namespace std;
diff --git a/libjulia/optimiser/InlinableExpressionFunctionFinder.cpp b/libjulia/optimiser/InlinableExpressionFunctionFinder.cpp
index 2097e091..e237063d 100644
--- a/libjulia/optimiser/InlinableExpressionFunctionFinder.cpp
+++ b/libjulia/optimiser/InlinableExpressionFunctionFinder.cpp
@@ -20,9 +20,9 @@
#include <libjulia/optimiser/InlinableExpressionFunctionFinder.h>
-#include <libsolidity/inlineasm/AsmData.h>
+#include <libjulia/optimiser/Utilities.h>
-#include <libsolidity/interface/Exceptions.h>
+#include <libsolidity/inlineasm/AsmData.h>
using namespace std;
using namespace dev;
@@ -56,7 +56,7 @@ void InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _fu
// We cannot overwrite previous settings, because this function definition
// would not be valid here if we were searching inside a functionally inlinable
// function body.
- solAssert(m_disallowedIdentifiers.empty() && !m_foundDisallowedIdentifier, "");
+ assertThrow(m_disallowedIdentifiers.empty() && !m_foundDisallowedIdentifier, OptimizerException, "");
m_disallowedIdentifiers = set<string>{retVariable, _function.name};
boost::apply_visitor(*this, *assignment.value);
if (!m_foundDisallowedIdentifier)
diff --git a/libjulia/optimiser/InlinableExpressionFunctionFinder.h b/libjulia/optimiser/InlinableExpressionFunctionFinder.h
index 36cb557a..d11160d7 100644
--- a/libjulia/optimiser/InlinableExpressionFunctionFinder.h
+++ b/libjulia/optimiser/InlinableExpressionFunctionFinder.h
@@ -23,8 +23,6 @@
#include <libjulia/ASTDataForward.h>
#include <libjulia/optimiser/ASTWalker.h>
-#include <libsolidity/interface/Exceptions.h>
-
#include <set>
namespace dev
diff --git a/libjulia/optimiser/MainFunction.cpp b/libjulia/optimiser/MainFunction.cpp
new file mode 100644
index 00000000..bcd2f178
--- /dev/null
+++ b/libjulia/optimiser/MainFunction.cpp
@@ -0,0 +1,54 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * Changes the topmost block to be a function with a specific name ("main") which has no
+ * inputs nor outputs.
+ */
+
+#include <libjulia/optimiser/MainFunction.h>
+
+#include <libjulia/optimiser/NameCollector.h>
+#include <libjulia/Exceptions.h>
+
+#include <libsolidity/inlineasm/AsmData.h>
+
+#include <libdevcore/CommonData.h>
+
+using namespace std;
+using namespace dev;
+using namespace dev::julia;
+using namespace dev::solidity;
+
+void MainFunction::operator()(Block& _block)
+{
+ assertThrow(_block.statements.size() >= 1, OptimizerException, "");
+ assertThrow(_block.statements[0].type() == typeid(Block), OptimizerException, "");
+ for (size_t i = 1; i < _block.statements.size(); ++i)
+ assertThrow(_block.statements.at(i).type() == typeid(FunctionDefinition), OptimizerException, "");
+ /// @todo this should handle scopes properly and instead of an assertion it should rename the conflicting function
+ assertThrow(NameCollector(_block).names().count("main") == 0, OptimizerException, "");
+
+ Block& block = boost::get<Block>(_block.statements[0]);
+ FunctionDefinition main{
+ block.location,
+ "main",
+ {},
+ {},
+ std::move(block)
+ };
+ _block.statements[0] = std::move(main);
+}
diff --git a/libjulia/optimiser/MainFunction.h b/libjulia/optimiser/MainFunction.h
new file mode 100644
index 00000000..7201d89a
--- /dev/null
+++ b/libjulia/optimiser/MainFunction.h
@@ -0,0 +1,41 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * Changes the topmost block to be a function with a specific name ("main") which has no
+ * inputs nor outputs.
+ */
+
+#pragma once
+
+#include <libjulia/ASTDataForward.h>
+
+namespace dev
+{
+namespace julia
+{
+
+/**
+ * Prerequisites: Function Grouper
+ */
+class MainFunction
+{
+public:
+ void operator()(Block& _block);
+};
+
+}
+}
diff --git a/libjulia/optimiser/README.md b/libjulia/optimiser/README.md
index e7134440..e8aa777a 100644
--- a/libjulia/optimiser/README.md
+++ b/libjulia/optimiser/README.md
@@ -87,3 +87,12 @@ simple rules like ``x + 0 == x`` to simplify expressions.
## Ineffective Statement Remover
This step removes statements that have no side-effects.
+
+## WebAssembly specific
+
+### Main Function
+
+Changes the topmost block to be a function with a specific name ("main") which has no
+inputs nor outputs.
+
+Depends on the Function Grouper.
diff --git a/libjulia/optimiser/Rematerialiser.cpp b/libjulia/optimiser/Rematerialiser.cpp
index eaa75e33..392099fb 100644
--- a/libjulia/optimiser/Rematerialiser.cpp
+++ b/libjulia/optimiser/Rematerialiser.cpp
@@ -22,6 +22,7 @@
#include <libjulia/optimiser/Metrics.h>
#include <libjulia/optimiser/ASTCopier.h>
+#include <libjulia/Exceptions.h>
#include <libsolidity/inlineasm/AsmData.h>
@@ -44,7 +45,7 @@ void Rematerialiser::visit(Expression& _e)
expressionValid = false;
break;
}
- solAssert(m_value.at(name), "");
+ assertThrow(m_value.at(name), OptimizerException, "");
auto const& value = *m_value.at(name);
if (expressionValid && CodeSize::codeSize(value) <= 7)
_e = (ASTCopier{}).translate(value);
diff --git a/libjulia/optimiser/Semantics.cpp b/libjulia/optimiser/Semantics.cpp
index 92728c46..f28925a4 100644
--- a/libjulia/optimiser/Semantics.cpp
+++ b/libjulia/optimiser/Semantics.cpp
@@ -20,6 +20,8 @@
#include <libjulia/optimiser/Semantics.h>
+#include <libjulia/Exceptions.h>
+
#include <libsolidity/inlineasm/AsmData.h>
#include <libevmasm/SemanticInformation.h>
@@ -56,5 +58,5 @@ void MovableChecker::operator()(FunctionCall const&)
void MovableChecker::visit(Statement const&)
{
- solAssert(false, "Movability for statement requested.");
+ assertThrow(false, OptimizerException, "Movability for statement requested.");
}
diff --git a/libjulia/optimiser/SyntacticalEquality.cpp b/libjulia/optimiser/SyntacticalEquality.cpp
index 2b90b091..c497336d 100644
--- a/libjulia/optimiser/SyntacticalEquality.cpp
+++ b/libjulia/optimiser/SyntacticalEquality.cpp
@@ -20,8 +20,9 @@
#include <libjulia/optimiser/SyntacticalEquality.h>
+#include <libjulia/Exceptions.h>
+
#include <libsolidity/inlineasm/AsmData.h>
-#include <libsolidity/interface/Exceptions.h>
#include <libdevcore/CommonData.h>
@@ -62,7 +63,7 @@ bool SyntacticalEqualityChecker::equal(Expression const& _e1, Expression const&
}
else
{
- solAssert(false, "Invlid expression");
+ assertThrow(false, OptimizerException, "Invalid expression");
}
return false;
}
diff --git a/libjulia/optimiser/UnusedPruner.cpp b/libjulia/optimiser/UnusedPruner.cpp
index 50038431..54e8fd6e 100644
--- a/libjulia/optimiser/UnusedPruner.cpp
+++ b/libjulia/optimiser/UnusedPruner.cpp
@@ -23,6 +23,7 @@
#include <libjulia/optimiser/NameCollector.h>
#include <libjulia/optimiser/Semantics.h>
#include <libjulia/optimiser/Utilities.h>
+#include <libjulia/Exceptions.h>
#include <libsolidity/inlineasm/AsmData.h>
@@ -108,8 +109,8 @@ void UnusedPruner::subtractReferences(map<string, size_t> const& _subtrahend)
{
for (auto const& ref: _subtrahend)
{
- solAssert(m_references.count(ref.first), "");
- solAssert(m_references.at(ref.first) >= ref.second, "");
+ assertThrow(m_references.count(ref.first), OptimizerException, "");
+ assertThrow(m_references.at(ref.first) >= ref.second, OptimizerException, "");
m_references[ref.first] -= ref.second;
m_shouldRunAgain = true;
}
diff --git a/libjulia/optimiser/Utilities.h b/libjulia/optimiser/Utilities.h
index e3b4b087..88ba3f47 100644
--- a/libjulia/optimiser/Utilities.h
+++ b/libjulia/optimiser/Utilities.h
@@ -22,16 +22,11 @@
#include <libjulia/ASTDataForward.h>
-#include <libdevcore/Exceptions.h>
-
namespace dev
{
namespace julia
{
-struct IuliaException: virtual Exception {};
-struct OptimizerException: virtual IuliaException {};
-
/// Removes statements that are just empty blocks (non-recursive).
void removeEmptyBlocks(Block& _block);
diff --git a/libsolidity/parsing/ParserBase.cpp b/libsolidity/parsing/ParserBase.cpp
index d0c7a551..71133746 100644
--- a/libsolidity/parsing/ParserBase.cpp
+++ b/libsolidity/parsing/ParserBase.cpp
@@ -106,10 +106,10 @@ void ParserBase::decreaseRecursionDepth()
void ParserBase::parserError(string const& _description)
{
- m_errorReporter.parserError(SourceLocation(position(), position(), sourceName()), _description);
+ m_errorReporter.parserError(SourceLocation(position(), endPosition(), sourceName()), _description);
}
void ParserBase::fatalParserError(string const& _description)
{
- m_errorReporter.fatalParserError(SourceLocation(position(), position(), sourceName()), _description);
+ m_errorReporter.fatalParserError(SourceLocation(position(), endPosition(), sourceName()), _description);
}
diff --git a/test/libjulia/MainFunction.cpp b/test/libjulia/MainFunction.cpp
new file mode 100644
index 00000000..c26b002d
--- /dev/null
+++ b/test/libjulia/MainFunction.cpp
@@ -0,0 +1,87 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @date 2018
+ * Unit tests for the Julia MainFunction transformation.
+ */
+
+#include <test/libjulia/Common.h>
+
+#include <libjulia/optimiser/FunctionGrouper.h>
+#include <libjulia/optimiser/MainFunction.h>
+
+#include <libsolidity/inlineasm/AsmPrinter.h>
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+using namespace dev::julia;
+using namespace dev::julia::test;
+using namespace dev::solidity;
+
+#define CHECK(_original, _expectation)\
+do\
+{\
+ assembly::AsmPrinter p(true);\
+ Block b = disambiguate(_original);\
+ (FunctionGrouper{})(b);\
+ (MainFunction{})(b);\
+ string result = p(b);\
+ BOOST_CHECK_EQUAL(result, format(_expectation));\
+}\
+while(false)
+
+BOOST_AUTO_TEST_SUITE(JuliaMainFunction)
+
+BOOST_AUTO_TEST_CASE(smoke_test)
+{
+ CHECK("{ }", "{ function main() { } }");
+}
+
+BOOST_AUTO_TEST_CASE(single_fun)
+{
+ CHECK(
+ "{ let a:u256 function f() {} }",
+ "{ function main() { let a:u256 } function f() {} }"
+ );
+}
+
+BOOST_AUTO_TEST_CASE(multi_fun_mixed)
+{
+ CHECK(
+ "{ let a:u256 function f() { let b:u256 } let c:u256 function g() { let d:u256 } let e:u256 }",
+ "{ function main() { let a:u256 let c:u256 let e:u256 } function f() { let b:u256 } function g() { let d:u256 } }"
+ );
+}
+
+BOOST_AUTO_TEST_CASE(nested_fun)
+{
+ CHECK(
+ "{ let a:u256 function f() { let b:u256 function g() { let c:u256} let d:u256 } }",
+ "{ function main() { let a:u256 } function f() { let b:u256 function g() { let c:u256} let d:u256 } }"
+ );
+}
+
+BOOST_AUTO_TEST_CASE(empty_block)
+{
+ CHECK(
+ "{ let a:u256 { } function f() -> x:bool { let b:u256 := 4:u256 {} for {} f() {} {} } }",
+ "{ function main() { let a:u256 { } } function f() -> x:bool { let b:u256 := 4:u256 {} for {} f() {} {} } }"
+ );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 71386010..3a4a2dad 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -10122,6 +10122,23 @@ BOOST_AUTO_TEST_CASE(shift_right_assignment)
ABI_CHECK(callContractFunction("f(uint256,uint256)", u256(0x4266), u256(17)), encodeArgs(u256(0)));
}
+BOOST_AUTO_TEST_CASE(shift_right_assignment_signed)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int a, int b) returns (int) {
+ a >>= b;
+ return a;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(0x4266), u256(0)), encodeArgs(u256(0x4266)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(0x4266), u256(8)), encodeArgs(u256(0x42)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(0x4266), u256(16)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(0x4266), u256(17)), encodeArgs(u256(0)));
+}
+
BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue)
{
char const* sourceCode = R"(
@@ -10133,9 +10150,141 @@ BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue)
)";
compileAndRun(sourceCode, 0, "C");
ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(0)), encodeArgs(u256(-4266)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(1)), encodeArgs(u256(-2133)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(4)), encodeArgs(u256(-266)));
ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(8)), encodeArgs(u256(-16)));
ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(16)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(17)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(0)), encodeArgs(u256(-4267)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(1)), encodeArgs(u256(-2133)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(4)), encodeArgs(u256(-266)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(8)), encodeArgs(u256(-16)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(16)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(17)), encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_int8)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int8 a, int8 b) returns (int) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(0)), encodeArgs(u256(-66)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(1)), encodeArgs(u256(-33)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(4)), encodeArgs(u256(-4)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(8)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(16)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-66), u256(17)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(0)), encodeArgs(u256(-67)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(1)), encodeArgs(u256(-33)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(4)), encodeArgs(u256(-4)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(8)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(16)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(-67), u256(17)), encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_signextend_int8)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int8 a, int8 b) returns (int8) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(0)), encodeArgs(u256(-103)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(1)), encodeArgs(u256(-51)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(2)), encodeArgs(u256(-25)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(4)), encodeArgs(u256(-6)));
+ ABI_CHECK(callContractFunction("f(int8,int8)", u256(0x99u), u256(8)), encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_signextend_int16)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int16 a, int16 b) returns (int16) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(0)), encodeArgs(u256(-103)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(1)), encodeArgs(u256(-51)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(2)), encodeArgs(u256(-25)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(4)), encodeArgs(u256(-6)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(0xFF99u), u256(8)), encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_signextend_int32)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int32 a, int32 b) returns (int32) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(0)), encodeArgs(u256(-103)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(1)), encodeArgs(u256(-51)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(2)), encodeArgs(u256(-25)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(4)), encodeArgs(u256(-6)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(0xFFFFFF99u), u256(8)), encodeArgs(u256(0)));
+}
+
+
+BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_int16)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int16 a, int16 b) returns (int) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(0)), encodeArgs(u256(-4266)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(1)), encodeArgs(u256(-2133)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(4)), encodeArgs(u256(-266)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(8)), encodeArgs(u256(-16)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(16)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4266), u256(17)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(0)), encodeArgs(u256(-4267)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(1)), encodeArgs(u256(-2133)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(4)), encodeArgs(u256(-266)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(8)), encodeArgs(u256(-16)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(16)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int16,int16)", u256(-4267), u256(17)), encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_int32)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f(int32 a, int32 b) returns (int) {
+ return a >> b;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(0)), encodeArgs(u256(-4266)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(1)), encodeArgs(u256(-2133)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(4)), encodeArgs(u256(-266)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(8)), encodeArgs(u256(-16)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(16)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4266), u256(17)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(0)), encodeArgs(u256(-4267)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(1)), encodeArgs(u256(-2133)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(4)), encodeArgs(u256(-266)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(8)), encodeArgs(u256(-16)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(16)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int32,int32)", u256(-4267), u256(17)), encodeArgs(u256(0)));
}
BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_assignment)
@@ -10150,9 +10299,17 @@ BOOST_AUTO_TEST_CASE(shift_right_negative_lvalue_assignment)
)";
compileAndRun(sourceCode, 0, "C");
ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(0)), encodeArgs(u256(-4266)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(1)), encodeArgs(u256(-2133)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(4)), encodeArgs(u256(-266)));
ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(8)), encodeArgs(u256(-16)));
ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(16)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4266), u256(17)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(0)), encodeArgs(u256(-4267)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(1)), encodeArgs(u256(-2133)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(4)), encodeArgs(u256(-266)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(8)), encodeArgs(u256(-16)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(16)), encodeArgs(u256(0)));
+ ABI_CHECK(callContractFunction("f(int256,int256)", u256(-4267), u256(17)), encodeArgs(u256(0)));
}
BOOST_AUTO_TEST_CASE(shift_negative_rvalue)
diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp
index 560c9013..63c03881 100644
--- a/test/libsolidity/StandardCompiler.cpp
+++ b/test/libsolidity/StandardCompiler.cpp
@@ -328,7 +328,7 @@ BOOST_AUTO_TEST_CASE(compilation_error)
dev::jsonCompactPrint(error),
"{\"component\":\"general\",\"formattedMessage\":\"fileA:1:23: ParserError: Expected identifier but got '}'\\n"
"contract A { function }\\n ^\\n\",\"message\":\"Expected identifier but got '}'\","
- "\"severity\":\"error\",\"sourceLocation\":{\"end\":22,\"file\":\"fileA\",\"start\":22},\"type\":\"ParserError\"}"
+ "\"severity\":\"error\",\"sourceLocation\":{\"end\":23,\"file\":\"fileA\",\"start\":22},\"type\":\"ParserError\"}"
);
}
}
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol
index 766b98b3..b89a3bb4 100644
--- a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol
@@ -5,4 +5,4 @@ contract C {
}
}
// ----
-// ParserError: (118-118): Expected ';' but got identifier
+// ParserError: (118-119): Expected ';' but got identifier
diff --git a/test/libsolidity/syntaxTests/parsing/constant_is_keyword.sol b/test/libsolidity/syntaxTests/parsing/constant_is_keyword.sol
index da3fa1c6..26d126ce 100644
--- a/test/libsolidity/syntaxTests/parsing/constant_is_keyword.sol
+++ b/test/libsolidity/syntaxTests/parsing/constant_is_keyword.sol
@@ -2,4 +2,4 @@ contract Foo {
uint constant = 4;
}
// ----
-// ParserError: (30-30): Expected identifier but got '='
+// ParserError: (30-31): Expected identifier but got '='
diff --git a/test/libsolidity/syntaxTests/parsing/emit_without_event.sol b/test/libsolidity/syntaxTests/parsing/emit_without_event.sol
index 1af1d4ab..b838b4af 100644
--- a/test/libsolidity/syntaxTests/parsing/emit_without_event.sol
+++ b/test/libsolidity/syntaxTests/parsing/emit_without_event.sol
@@ -5,4 +5,4 @@ contract C {
}
}
// ----
-// ParserError: (49-49): Expected '(' but got ';'
+// ParserError: (49-50): Expected '(' but got ';'
diff --git a/test/libsolidity/syntaxTests/parsing/empty_enum.sol b/test/libsolidity/syntaxTests/parsing/empty_enum.sol
index dd786cdc..483f6a91 100644
--- a/test/libsolidity/syntaxTests/parsing/empty_enum.sol
+++ b/test/libsolidity/syntaxTests/parsing/empty_enum.sol
@@ -2,4 +2,4 @@ contract c {
enum foo { }
}
// ----
-// ParserError: (25-25): enum with no members is not allowed.
+// ParserError: (25-26): enum with no members is not allowed.
diff --git a/test/libsolidity/syntaxTests/parsing/event_with_no_argument_list.sol b/test/libsolidity/syntaxTests/parsing/event_with_no_argument_list.sol
index 850c3627..b38c7dc9 100644
--- a/test/libsolidity/syntaxTests/parsing/event_with_no_argument_list.sol
+++ b/test/libsolidity/syntaxTests/parsing/event_with_no_argument_list.sol
@@ -2,4 +2,4 @@ contract c {
event e;
}
// ----
-// ParserError: (21-21): Expected '(' but got ';'
+// ParserError: (21-22): Expected '(' but got ';'
diff --git a/test/libsolidity/syntaxTests/parsing/external_variable.sol b/test/libsolidity/syntaxTests/parsing/external_variable.sol
index 2de70e23..2a02d19a 100644
--- a/test/libsolidity/syntaxTests/parsing/external_variable.sol
+++ b/test/libsolidity/syntaxTests/parsing/external_variable.sol
@@ -2,4 +2,4 @@ contract c {
uint external x;
}
// ----
-// ParserError: (19-19): Expected identifier but got 'external'
+// ParserError: (19-27): Expected identifier but got 'external'
diff --git a/test/libsolidity/syntaxTests/parsing/fixed_literal_with_double_radix.sol b/test/libsolidity/syntaxTests/parsing/fixed_literal_with_double_radix.sol
index b3adc03d..0d5734aa 100644
--- a/test/libsolidity/syntaxTests/parsing/fixed_literal_with_double_radix.sol
+++ b/test/libsolidity/syntaxTests/parsing/fixed_literal_with_double_radix.sol
@@ -2,4 +2,4 @@ contract A {
fixed40x40 pi = 3.14.15;
}
// ----
-// ParserError: (34-34): Expected ';' but got 'Number'
+// ParserError: (34-37): Expected ';' but got 'Number'
diff --git a/test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable_with_modifiers.sol b/test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable_with_modifiers.sol
index 198d250b..6c22f4b7 100644
--- a/test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable_with_modifiers.sol
+++ b/test/libsolidity/syntaxTests/parsing/function_type_as_storage_variable_with_modifiers.sol
@@ -2,4 +2,4 @@ contract test {
function (uint, uint) modifier1() returns (uint) f1;
}
// ----
-// ParserError: (66-66): Expected '{' but got identifier
+// ParserError: (66-68): Expected '{' but got identifier
diff --git a/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_lvalue.sol b/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_lvalue.sol
index 23052980..9460751c 100644
--- a/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_lvalue.sol
+++ b/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_lvalue.sol
@@ -6,4 +6,4 @@ contract c {
}
}
// ----
-// ParserError: (62-62): Expected expression (inline array elements cannot be omitted).
+// ParserError: (62-63): Expected expression (inline array elements cannot be omitted).
diff --git a/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_without_lvalue.sol b/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_without_lvalue.sol
index 88c67619..5b78232d 100644
--- a/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_without_lvalue.sol
+++ b/test/libsolidity/syntaxTests/parsing/inline_array_empty_cells_check_without_lvalue.sol
@@ -5,4 +5,4 @@ contract c {
}
}
// ----
-// ParserError: (75-75): Expected expression (inline array elements cannot be omitted).
+// ParserError: (75-76): Expected expression (inline array elements cannot be omitted).
diff --git a/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol b/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol
index e0c8fa9a..fb267ba3 100644
--- a/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol
+++ b/test/libsolidity/syntaxTests/parsing/invalid_fixed_conversion_leading_zeroes_check.sol
@@ -4,4 +4,4 @@ contract test {
}
}
// ----
-// ParserError: (44-44): Expected primary expression.
+// ParserError: (44-47): Expected primary expression.
diff --git a/test/libsolidity/syntaxTests/parsing/local_const_variable.sol b/test/libsolidity/syntaxTests/parsing/local_const_variable.sol
index f06e2501..505fe0b5 100644
--- a/test/libsolidity/syntaxTests/parsing/local_const_variable.sol
+++ b/test/libsolidity/syntaxTests/parsing/local_const_variable.sol
@@ -6,4 +6,4 @@ contract Foo {
}
}
// ----
-// ParserError: (67-67): Expected ';' but got 'constant'
+// ParserError: (67-75): Expected ';' but got 'constant'
diff --git a/test/libsolidity/syntaxTests/parsing/location_specifiers_for_state_variables.sol b/test/libsolidity/syntaxTests/parsing/location_specifiers_for_state_variables.sol
index 9cc7a4fa..40eaf838 100644
--- a/test/libsolidity/syntaxTests/parsing/location_specifiers_for_state_variables.sol
+++ b/test/libsolidity/syntaxTests/parsing/location_specifiers_for_state_variables.sol
@@ -2,4 +2,4 @@ contract Foo {
uint[] memory x;
}
// ----
-// ParserError: (23-23): Expected identifier but got 'memory'
+// ParserError: (23-29): Expected identifier but got 'memory'
diff --git a/test/libsolidity/syntaxTests/parsing/location_specifiers_with_var.sol b/test/libsolidity/syntaxTests/parsing/location_specifiers_with_var.sol
index 47fe37d5..2b8f08c5 100644
--- a/test/libsolidity/syntaxTests/parsing/location_specifiers_with_var.sol
+++ b/test/libsolidity/syntaxTests/parsing/location_specifiers_with_var.sol
@@ -2,4 +2,4 @@ contract Foo {
function f() { var memory x; }
}
// ----
-// ParserError: (35-35): Location specifier needs explicit type name.
+// ParserError: (35-41): Location specifier needs explicit type name.
diff --git a/test/libsolidity/syntaxTests/parsing/malformed_enum_declaration.sol b/test/libsolidity/syntaxTests/parsing/malformed_enum_declaration.sol
index 9fc7efff..811b4219 100644
--- a/test/libsolidity/syntaxTests/parsing/malformed_enum_declaration.sol
+++ b/test/libsolidity/syntaxTests/parsing/malformed_enum_declaration.sol
@@ -2,4 +2,4 @@ contract c {
enum foo { WARNING,}
}
// ----
-// ParserError: (33-33): Expected identifier after ','
+// ParserError: (33-34): Expected identifier after ','
diff --git a/test/libsolidity/syntaxTests/parsing/missing_argument_in_named_args.sol b/test/libsolidity/syntaxTests/parsing/missing_argument_in_named_args.sol
index 8e0acfaa..f7c3fb31 100644
--- a/test/libsolidity/syntaxTests/parsing/missing_argument_in_named_args.sol
+++ b/test/libsolidity/syntaxTests/parsing/missing_argument_in_named_args.sol
@@ -3,4 +3,4 @@ contract test {
function b() returns (uint r) { r = a({a: , b: , c: }); }
}
// ----
-// ParserError: (146-146): Expected primary expression.
+// ParserError: (146-147): Expected primary expression.
diff --git a/test/libsolidity/syntaxTests/parsing/missing_parameter_name_in_named_args.sol b/test/libsolidity/syntaxTests/parsing/missing_parameter_name_in_named_args.sol
index b950c76a..d7c2f2be 100644
--- a/test/libsolidity/syntaxTests/parsing/missing_parameter_name_in_named_args.sol
+++ b/test/libsolidity/syntaxTests/parsing/missing_parameter_name_in_named_args.sol
@@ -3,4 +3,4 @@ contract test {
function b() returns (uint r) { r = a({: 1, : 2, : 3}); }
}
// ----
-// ParserError: (143-143): Expected identifier but got ':'
+// ParserError: (143-144): Expected identifier but got ':'
diff --git a/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol b/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol
index 15927f50..51b7bd24 100644
--- a/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol
+++ b/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol
@@ -2,4 +2,4 @@ contract test {
uint256 ;
}
// ----
-// ParserError: (28-28): Expected identifier but got ';'
+// ParserError: (28-29): Expected identifier but got ';'
diff --git a/test/libsolidity/syntaxTests/parsing/modifier_without_semicolon.sol b/test/libsolidity/syntaxTests/parsing/modifier_without_semicolon.sol
index 1b488837..a9fa33e6 100644
--- a/test/libsolidity/syntaxTests/parsing/modifier_without_semicolon.sol
+++ b/test/libsolidity/syntaxTests/parsing/modifier_without_semicolon.sol
@@ -2,4 +2,4 @@ contract c {
modifier mod { if (msg.sender == 0) _ }
}
// ----
-// ParserError: (52-52): Expected ';' but got '}'
+// ParserError: (52-53): Expected ';' but got '}'
diff --git a/test/libsolidity/syntaxTests/parsing/new_invalid_type_name.sol b/test/libsolidity/syntaxTests/parsing/new_invalid_type_name.sol
index 31cd1f09..d469bc75 100644
--- a/test/libsolidity/syntaxTests/parsing/new_invalid_type_name.sol
+++ b/test/libsolidity/syntaxTests/parsing/new_invalid_type_name.sol
@@ -4,4 +4,4 @@ contract C {
}
}
// ----
-// ParserError: (35-35): Expected explicit type name.
+// ParserError: (35-38): Expected explicit type name.
diff --git a/test/libsolidity/syntaxTests/parsing/payable_accessor.sol b/test/libsolidity/syntaxTests/parsing/payable_accessor.sol
index 46bf6e13..6504004b 100644
--- a/test/libsolidity/syntaxTests/parsing/payable_accessor.sol
+++ b/test/libsolidity/syntaxTests/parsing/payable_accessor.sol
@@ -2,4 +2,4 @@ contract test {
uint payable x;
}
// ----
-// ParserError: (22-22): Expected identifier but got 'payable'
+// ParserError: (22-29): Expected identifier but got 'payable'
diff --git a/test/libsolidity/syntaxTests/parsing/return_var.sol b/test/libsolidity/syntaxTests/parsing/return_var.sol
index 47ac9ef0..b9ce8f95 100644
--- a/test/libsolidity/syntaxTests/parsing/return_var.sol
+++ b/test/libsolidity/syntaxTests/parsing/return_var.sol
@@ -9,17 +9,17 @@ contract C {
function f() public pure returns (var storage x, var storage y) {}
}
// ----
-// ParserError: (38-38): Expected explicit type name.
-// ParserError: (71-71): Expected explicit type name.
-// ParserError: (106-106): Expected explicit type name.
-// ParserError: (157-157): Expected explicit type name.
-// ParserError: (192-192): Expected explicit type name.
-// ParserError: (199-199): Expected explicit type name.
-// ParserError: (247-247): Expected explicit type name.
-// ParserError: (251-251): Location specifier needs explicit type name.
-// ParserError: (301-301): Expected explicit type name.
-// ParserError: (305-305): Location specifier needs explicit type name.
-// ParserError: (357-357): Expected explicit type name.
-// ParserError: (361-361): Location specifier needs explicit type name.
-// ParserError: (372-372): Expected explicit type name.
-// ParserError: (376-376): Location specifier needs explicit type name.
+// ParserError: (38-41): Expected explicit type name.
+// ParserError: (71-74): Expected explicit type name.
+// ParserError: (106-109): Expected explicit type name.
+// ParserError: (157-160): Expected explicit type name.
+// ParserError: (192-195): Expected explicit type name.
+// ParserError: (199-202): Expected explicit type name.
+// ParserError: (247-250): Expected explicit type name.
+// ParserError: (251-258): Location specifier needs explicit type name.
+// ParserError: (301-304): Expected explicit type name.
+// ParserError: (305-312): Location specifier needs explicit type name.
+// ParserError: (357-360): Expected explicit type name.
+// ParserError: (361-368): Location specifier needs explicit type name.
+// ParserError: (372-375): Expected explicit type name.
+// ParserError: (376-383): Location specifier needs explicit type name.
diff --git a/test/libsolidity/syntaxTests/parsing/single_function_param_trailing_comma.sol b/test/libsolidity/syntaxTests/parsing/single_function_param_trailing_comma.sol
index 1febdab9..fe52b3b2 100644
--- a/test/libsolidity/syntaxTests/parsing/single_function_param_trailing_comma.sol
+++ b/test/libsolidity/syntaxTests/parsing/single_function_param_trailing_comma.sol
@@ -2,4 +2,4 @@ contract test {
function(uint a,) {}
}
// ----
-// ParserError: (32-32): Unexpected trailing comma in parameter list.
+// ParserError: (32-33): Unexpected trailing comma in parameter list.
diff --git a/test/libsolidity/syntaxTests/parsing/single_return_param_trailing_comma.sol b/test/libsolidity/syntaxTests/parsing/single_return_param_trailing_comma.sol
index d2e3bbb3..99f91819 100644
--- a/test/libsolidity/syntaxTests/parsing/single_return_param_trailing_comma.sol
+++ b/test/libsolidity/syntaxTests/parsing/single_return_param_trailing_comma.sol
@@ -2,4 +2,4 @@ contract test {
function() returns (uint a,) {}
}
// ----
-// ParserError: (43-43): Unexpected trailing comma in parameter list.
+// ParserError: (43-44): Unexpected trailing comma in parameter list.
diff --git a/test/libsolidity/syntaxTests/parsing/trailing_comma_in_named_args.sol b/test/libsolidity/syntaxTests/parsing/trailing_comma_in_named_args.sol
index 22efc58a..8fc3dab8 100644
--- a/test/libsolidity/syntaxTests/parsing/trailing_comma_in_named_args.sol
+++ b/test/libsolidity/syntaxTests/parsing/trailing_comma_in_named_args.sol
@@ -3,4 +3,4 @@ contract test {
function b() returns (uint r) { r = a({a: 1, b: 2, c: 3, }); }
}
// ----
-// ParserError: (159-159): Unexpected trailing comma.
+// ParserError: (159-160): Unexpected trailing comma.
diff --git a/test/libsolidity/syntaxTests/parsing/tuples_without_commas.sol b/test/libsolidity/syntaxTests/parsing/tuples_without_commas.sol
index e283e0bb..fcbb875c 100644
--- a/test/libsolidity/syntaxTests/parsing/tuples_without_commas.sol
+++ b/test/libsolidity/syntaxTests/parsing/tuples_without_commas.sol
@@ -4,4 +4,4 @@ contract C {
}
}
// ----
-// ParserError: (42-42): Expected ',' but got 'Number'
+// ParserError: (42-43): Expected ',' but got 'Number'
diff --git a/test/libsolidity/syntaxTests/parsing/var_array.sol b/test/libsolidity/syntaxTests/parsing/var_array.sol
index d635a04b..e08f5511 100644
--- a/test/libsolidity/syntaxTests/parsing/var_array.sol
+++ b/test/libsolidity/syntaxTests/parsing/var_array.sol
@@ -2,4 +2,4 @@ contract Foo {
function f() { var[] a; }
}
// ----
-// ParserError: (34-34): Expected identifier but got '['
+// ParserError: (34-35): Expected identifier but got '['
diff --git a/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol b/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol
index e041247d..2e5a9c58 100644
--- a/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol
+++ b/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol
@@ -9,17 +9,17 @@ contract C {
function f(var storage x, var storage y) public pure {}
}
// ----
-// ParserError: (28-28): Expected explicit type name.
-// ParserError: (63-63): Expected explicit type name.
-// ParserError: (100-100): Expected explicit type name.
-// ParserError: (107-107): Expected explicit type name.
-// ParserError: (152-152): Expected explicit type name.
-// ParserError: (189-189): Expected explicit type name.
-// ParserError: (234-234): Expected explicit type name.
-// ParserError: (238-238): Location specifier needs explicit type name.
-// ParserError: (277-277): Expected explicit type name.
-// ParserError: (281-281): Location specifier needs explicit type name.
-// ParserError: (322-322): Expected explicit type name.
-// ParserError: (326-326): Location specifier needs explicit type name.
-// ParserError: (337-337): Expected explicit type name.
-// ParserError: (341-341): Location specifier needs explicit type name.
+// ParserError: (28-31): Expected explicit type name.
+// ParserError: (63-66): Expected explicit type name.
+// ParserError: (100-103): Expected explicit type name.
+// ParserError: (107-110): Expected explicit type name.
+// ParserError: (152-155): Expected explicit type name.
+// ParserError: (189-192): Expected explicit type name.
+// ParserError: (234-237): Expected explicit type name.
+// ParserError: (238-245): Location specifier needs explicit type name.
+// ParserError: (277-280): Expected explicit type name.
+// ParserError: (281-288): Location specifier needs explicit type name.
+// ParserError: (322-325): Expected explicit type name.
+// ParserError: (326-333): Location specifier needs explicit type name.
+// ParserError: (337-340): Expected explicit type name.
+// ParserError: (341-348): Location specifier needs explicit type name.
diff --git a/test/libsolidity/syntaxTests/parsing/var_storage_var.sol b/test/libsolidity/syntaxTests/parsing/var_storage_var.sol
index 431d4ca5..6e4ccfa5 100644
--- a/test/libsolidity/syntaxTests/parsing/var_storage_var.sol
+++ b/test/libsolidity/syntaxTests/parsing/var_storage_var.sol
@@ -2,4 +2,4 @@ contract C {
var a;
}
// ----
-// ParserError: (17-17): Function, variable, struct or modifier declaration expected.
+// ParserError: (17-20): Function, variable, struct or modifier declaration expected.
diff --git a/test/libsolidity/syntaxTests/parsing/variable_definition_in_mapping.sol b/test/libsolidity/syntaxTests/parsing/variable_definition_in_mapping.sol
index ec55a4db..61f5be53 100644
--- a/test/libsolidity/syntaxTests/parsing/variable_definition_in_mapping.sol
+++ b/test/libsolidity/syntaxTests/parsing/variable_definition_in_mapping.sol
@@ -4,4 +4,4 @@ contract test {
}
}
// ----
-// ParserError: (44-44): Expected elementary type name for mapping key type
+// ParserError: (44-47): Expected elementary type name for mapping key type