aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml2
-rw-r--r--Changelog.md1
-rw-r--r--appveyor.yml2
-rw-r--r--cmake/FindCLN.cmake5
-rw-r--r--cmake/FindCVC4.cmake11
-rw-r--r--cmake/FindGMP.cmake7
-rw-r--r--cmake/FindZ3.cmake9
-rw-r--r--cmake/jsoncpp.cmake1
-rw-r--r--docs/contributing.rst4
-rw-r--r--docs/installing-solidity.rst4
-rw-r--r--docs/types.rst62
-rw-r--r--libdevcore/CMakeLists.txt2
-rw-r--r--libevmasm/AssemblyItem.h25
-rw-r--r--libevmasm/PeepholeOptimiser.cpp8
-rw-r--r--libevmasm/SemanticInformation.cpp2
-rw-r--r--libsolidity/CMakeLists.txt6
-rw-r--r--libsolidity/analysis/SyntaxChecker.cpp2
-rw-r--r--libsolidity/interface/CompilerStack.cpp25
-rw-r--r--libsolidity/interface/CompilerStack.h8
-rw-r--r--libsolidity/interface/StandardCompiler.cpp90
-rw-r--r--libsolidity/parsing/Parser.cpp25
-rw-r--r--libsolidity/parsing/Parser.h1
-rw-r--r--test/cmdlineTests/standard_wrong_type_auxiliary_input.json11
-rw-r--r--test/cmdlineTests/standard_wrong_type_auxiliary_input.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_auxiliary_input.json.stdout2
-rw-r--r--test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json20
-rw-r--r--test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json23
-rw-r--r--test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_metadata.json19
-rw-r--r--test/cmdlineTests/standard_wrong_type_metadata.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_metadata.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_optimizer.json18
-rw-r--r--test/cmdlineTests/standard_wrong_type_optimizer.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_optimizer.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection.json11
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection_contract.json16
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection_contract.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection_contract.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection_file.json13
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection_file.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection_file.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection_output.json16
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection_output.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_output_selection_output.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_remappings.json17
-rw-r--r--test/cmdlineTests/standard_wrong_type_remappings.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_remappings.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_remappings_entry.json17
-rw-r--r--test/cmdlineTests/standard_wrong_type_remappings_entry.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_remappings_entry.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_root.json1
-rw-r--r--test/cmdlineTests/standard_wrong_type_root.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_root.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_settings.json23
-rw-r--r--test/cmdlineTests/standard_wrong_type_settings.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_settings.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_source.json12
-rw-r--r--test/cmdlineTests/standard_wrong_type_source.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_source.json.stdout1
-rw-r--r--test/cmdlineTests/standard_wrong_type_sources.json4
-rw-r--r--test/cmdlineTests/standard_wrong_type_sources.json.exit1
-rw-r--r--test/cmdlineTests/standard_wrong_type_sources.json.stdout1
-rw-r--r--test/libsolidity/AnalysisFramework.cpp2
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp12
-rw-r--r--test/libsolidity/SolidityParser.cpp17
70 files changed, 496 insertions, 89 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index c13bef35..cec69e31 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -15,7 +15,7 @@ defaults:
mkdir -p build
cd build
[ -n "$COVERAGE" -a "$CIRCLE_BRANCH" != release -a -z "$CIRCLE_TAG" ] && CMAKE_OPTIONS="$CMAKE_OPTIONS -DCOVERAGE=ON"
- cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo $CMAKE_OPTIONS
+ cmake .. -DCMAKE_BUILD_TYPE=Release $CMAKE_OPTIONS
make -j4
- run_tests: &run_tests
name: Tests
diff --git a/Changelog.md b/Changelog.md
index 63c0280a..60e3904c 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -17,6 +17,7 @@ Compiler Features:
Bugfixes:
+ * Compiler Interface: Report specific error message for json input errors instead of internal compiler error
Build System:
diff --git a/appveyor.yml b/appveyor.yml
index 5377925e..864c6359 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -32,7 +32,7 @@ branches:
- release
- develop
configuration:
- - RelWithDebInfo
+ - Release
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
diff --git a/cmake/FindCLN.cmake b/cmake/FindCLN.cmake
index f2234bb4..0b574ab9 100644
--- a/cmake/FindCLN.cmake
+++ b/cmake/FindCLN.cmake
@@ -1,3 +1,8 @@
find_library(CLN_LIBRARY NAMES cln)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CLN DEFAULT_MSG CLN_LIBRARY)
+
+if(CLN_FOUND AND NOT TARGET CLN::CLN)
+ add_library(CLN::CLN UNKNOWN IMPORTED)
+ set_property(TARGET CLN::CLN PROPERTY IMPORTED_LOCATION ${CLN_LIBRARY})
+endif()
diff --git a/cmake/FindCVC4.cmake b/cmake/FindCVC4.cmake
index 2649d7c7..887b907b 100644
--- a/cmake/FindCVC4.cmake
+++ b/cmake/FindCVC4.cmake
@@ -14,12 +14,19 @@ if (USE_CVC4)
set(CVC4_LIBRARIES ${CVC4_LIBRARY})
if (CLN_FOUND)
- set(CVC4_LIBRARIES ${CVC4_LIBRARIES} ${CLN_LIBRARY})
+ set(CVC4_LIBRARIES ${CVC4_LIBRARIES} CLN::CLN)
endif ()
if (GMP_FOUND)
- set(CVC4_LIBRARIES ${CVC4_LIBRARIES} ${GMP_LIBRARY})
+ set(CVC4_LIBRARIES ${CVC4_LIBRARIES} GMP::GMP)
endif ()
+
+ if (NOT TARGET CVC4::CVC4)
+ add_library(CVC4::CVC4 UNKNOWN IMPORTED)
+ set_property(TARGET CVC4::CVC4 PROPERTY IMPORTED_LOCATION ${CVC4_LIBRARY})
+ set_property(TARGET CVC4::CVC4 PROPERTY INTERFACE_LINK_LIBRARIES ${CVC4_LIBRARIES})
+ set_property(TARGET CVC4::CVC4 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CVC4_INCLUDE_DIR})
+ endif()
endif()
else()
set(CVC4_FOUND FALSE)
diff --git a/cmake/FindGMP.cmake b/cmake/FindGMP.cmake
index 8abe354c..c3a02654 100644
--- a/cmake/FindGMP.cmake
+++ b/cmake/FindGMP.cmake
@@ -1,3 +1,8 @@
-find_library(GMP_LIBRARY NAMES gmp )
+find_library(GMP_LIBRARY NAMES gmp)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GMP DEFAULT_MSG GMP_LIBRARY)
+
+if(GMP_FOUND AND NOT TARGET GMP::GMP)
+ add_library(GMP::GMP UNKNOWN IMPORTED)
+ set_property(TARGET GMP::GMP PROPERTY IMPORTED_LOCATION ${GMP_LIBRARY})
+endif()
diff --git a/cmake/FindZ3.cmake b/cmake/FindZ3.cmake
index c017cac2..ad34cbc3 100644
--- a/cmake/FindZ3.cmake
+++ b/cmake/FindZ3.cmake
@@ -1,9 +1,14 @@
if (USE_Z3)
find_path(Z3_INCLUDE_DIR NAMES z3++.h PATH_SUFFIXES z3)
- find_library(Z3_LIBRARY NAMES z3 )
+ find_library(Z3_LIBRARY NAMES z3)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Z3 DEFAULT_MSG Z3_LIBRARY Z3_INCLUDE_DIR)
+
+ if (NOT TARGET Z3::Z3)
+ add_library(Z3::Z3 UNKNOWN IMPORTED)
+ set_property(TARGET Z3::Z3 PROPERTY IMPORTED_LOCATION ${Z3_LIBRARY})
+ set_property(TARGET Z3::Z3 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${Z3_INCLUDE_DIR})
+ endif()
else()
set(Z3_FOUND FALSE)
endif()
-# TODO: Create IMPORTED library for Z3.
diff --git a/cmake/jsoncpp.cmake b/cmake/jsoncpp.cmake
index 318a526e..4db7b9c3 100644
--- a/cmake/jsoncpp.cmake
+++ b/cmake/jsoncpp.cmake
@@ -51,5 +51,6 @@ ExternalProject_Add(jsoncpp-project
add_library(jsoncpp STATIC IMPORTED)
file(MAKE_DIRECTORY ${JSONCPP_INCLUDE_DIR}) # Must exist.
set_property(TARGET jsoncpp PROPERTY IMPORTED_LOCATION ${JSONCPP_LIBRARY})
+set_property(TARGET jsoncpp PROPERTY INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${JSONCPP_INCLUDE_DIR})
set_property(TARGET jsoncpp PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${JSONCPP_INCLUDE_DIR})
add_dependencies(jsoncpp jsoncpp-project)
diff --git a/docs/contributing.rst b/docs/contributing.rst
index 41573ea1..85816766 100644
--- a/docs/contributing.rst
+++ b/docs/contributing.rst
@@ -83,8 +83,8 @@ internally.
.. note ::
- Those working in a Windows environment wanting to run the above basic sets without aleth or libz3 in Git Bash, you would have to do: ``./build/test/RelWithDebInfo/soltest.exe -- --no-ipc --no-smt``.
- If you're running this in plain Command Prompt, use ``.\build\test\RelWithDebInfo\soltest.exe -- --no-ipc --no-smt``.
+ Those working in a Windows environment wanting to run the above basic sets without aleth or libz3 in Git Bash, you would have to do: ``./build/test/Release/soltest.exe -- --no-ipc --no-smt``.
+ If you're running this in plain Command Prompt, use ``.\build\test\Release\soltest.exe -- --no-ipc --no-smt``.
The option ``--no-smt`` disables the tests that require ``libz3`` and
``--no-ipc`` disables those that require ``aleth``.
diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst
index 2797d8b0..c475d427 100644
--- a/docs/installing-solidity.rst
+++ b/docs/installing-solidity.rst
@@ -296,13 +296,13 @@ And for Windows:
This latter set of instructions should result in the creation of
**solidity.sln** in that build directory. Double-clicking on that file
should result in Visual Studio firing up. We suggest building
-**RelWithDebugInfo** configuration, but all others work.
+**Release** configuration, but all others work.
Alternatively, you can build for Windows on the command-line, like so:
.. code-block:: bash
- cmake --build . --config RelWithDebInfo
+ cmake --build . --config Release
CMake options
=============
diff --git a/docs/types.rst b/docs/types.rst
index dcd5f644..08fbd7b3 100644
--- a/docs/types.rst
+++ b/docs/types.rst
@@ -811,40 +811,50 @@ Data locations are not only relevant for persistency of data, but also for the s
Arrays
------
-Arrays can have a compile-time fixed size or they can be dynamic.
-The are few restrictions for the element, it can also be
-another array, a mapping or a struct. The general restrictions for
-types apply, though, in that mappings can only be used in storage
-and publicly-visible functions need parameters that are :ref:`ABI types <ABI>`.
-
-An array of fixed size ``k`` and element type ``T`` is written as ``T[k]``,
-an array of dynamic size as ``T[]``. As an example, an array of 5 dynamic
-arrays of ``uint`` is ``uint[][5]`` (note that the notation is reversed when
-compared to some other languages). To access the second uint in the
-third dynamic array, you use ``x[2][1]`` (indices are zero-based and
-access works in the opposite way of the declaration, i.e. ``x[2]``
-shaves off one level in the type from the right).
-
-Accessing an array past its end causes a revert. If you want to add
-new elements, you have to use ``.push()`` or increase the ``.length``
-member (see below).
+Arrays can have a compile-time fixed size, or they can have a dynamic size.
+
+The type of an array of fixed size ``k`` and element type ``T`` is written as ``T[k]``,
+and an array of dynamic size as ``T[]``.
+
+For example, an array of 5 dynamic arrays of ``uint`` is written as
+``uint[][5]``. The notation is reversed compared to some other languages. In
+Solidity, ``X[3]`` is always an array containing three elements of type ``X``,
+even if ``X`` is itself an array. This is not the case in other languages such
+as C.
+
+Indices are zero-based, and access is in the opposite direction of the
+declaration.
+
+For example, if you have a variable ``uint[][5] x memory``, you access the
+second ``uint`` in the third dynamic array using ``x[2][1]``, and to access the
+third dynamic array, use ``x[2]``. Again,
+if you have an array ``T[5] a`` for a type ``T`` that can also be an array,
+then ``a[2]`` always has type ``T``.
+
+Array elements can be of any type, including mapping or struct. The general
+restrictions for types apply, in that mappings can only be stored in the
+``storage`` data location and publicly-visible functions need parameters that are :ref:`ABI types <ABI>`.
+
+Accessing an array past its end causes a failing assertion. You can use the ``.push()`` method to append a new element at the end or assign to the ``.length`` :ref:`member <array-members>` to change the size (see below for caveats).
+method or increase the ``.length`` :ref:`member <array-members>` to add elements.
Variables of type ``bytes`` and ``string`` are special arrays. A ``bytes`` is similar to ``byte[]``,
but it is packed tightly in calldata and memory. ``string`` is equal to ``bytes`` but does not allow
length or index access.
-So ``bytes`` should always be preferred over ``byte[]`` because it is cheaper.
-As a rule of thumb, use ``bytes`` for arbitrary-length raw byte data and ``string``
-for arbitrary-length string (UTF-8) data. If you can limit the length to a certain
-number of bytes, always use one of ``bytes1`` to ``bytes32`` because they are much cheaper.
+
+You should use ``bytes`` over ``byte[]`` because it is cheaper, since ``byte[]`` adds 31 padding bytes between the elements. As a general rule,
+use ``bytes`` for arbitrary-length raw byte data and ``string`` for arbitrary-length
+string (UTF-8) data. If you can limit the length to a certain number of bytes,
+always use one of the value types ``bytes1`` to ``bytes32`` because they are much cheaper.
.. note::
If you want to access the byte-representation of a string ``s``, use
``bytes(s).length`` / ``bytes(s)[7] = 'x';``. Keep in mind
that you are accessing the low-level bytes of the UTF-8 representation,
- and not the individual characters!
+ and not the individual characters.
It is possible to mark arrays ``public`` and have Solidity create a :ref:`getter <visibility-and-getters>`.
-The numeric index will become a required parameter for the getter.
+The numeric index becomes a required parameter for the getter.
.. index:: ! array;allocating, new
@@ -918,8 +928,10 @@ complications because of how arrays are passed in the ABI.
.. index:: ! array;length, length, push, pop, !array;push, !array;pop
-Members
-^^^^^^^
+.. _array-members:
+
+Array Members
+^^^^^^^^^^^^^
**length**:
Arrays have a ``length`` member that contains their number of elements.
diff --git a/libdevcore/CMakeLists.txt b/libdevcore/CMakeLists.txt
index e2309b16..e68ac10a 100644
--- a/libdevcore/CMakeLists.txt
+++ b/libdevcore/CMakeLists.txt
@@ -30,7 +30,7 @@ set(sources
)
add_library(devcore ${sources})
-target_link_libraries(devcore PRIVATE jsoncpp ${Boost_FILESYSTEM_LIBRARIES} ${Boost_REGEX_LIBRARIES} ${Boost_SYSTEM_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+target_link_libraries(devcore PUBLIC jsoncpp ${Boost_FILESYSTEM_LIBRARIES} ${Boost_REGEX_LIBRARIES} ${Boost_SYSTEM_LIBRARIES} Threads::Threads)
target_include_directories(devcore PUBLIC "${CMAKE_SOURCE_DIR}")
target_include_directories(devcore SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
add_dependencies(devcore solidity_BuildInfo.h)
diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h
index a7875171..d21be199 100644
--- a/libevmasm/AssemblyItem.h
+++ b/libevmasm/AssemblyItem.h
@@ -57,22 +57,26 @@ class AssemblyItem
public:
enum class JumpType { Ordinary, IntoFunction, OutOfFunction };
- AssemblyItem(u256 _push, langutil::SourceLocation const& _location = langutil::SourceLocation()):
- AssemblyItem(Push, _push, _location) { }
- AssemblyItem(solidity::Instruction _i, langutil::SourceLocation const& _location = langutil::SourceLocation()):
+ AssemblyItem(u256 _push, langutil::SourceLocation _location = langutil::SourceLocation()):
+ AssemblyItem(Push, std::move(_push), std::move(_location)) { }
+ AssemblyItem(solidity::Instruction _i, langutil::SourceLocation _location = langutil::SourceLocation()):
m_type(Operation),
m_instruction(_i),
- m_location(_location)
+ m_location(std::move(_location))
{}
- AssemblyItem(AssemblyItemType _type, u256 _data = 0, langutil::SourceLocation const& _location = langutil::SourceLocation()):
+ AssemblyItem(AssemblyItemType _type, u256 _data = 0, langutil::SourceLocation _location = langutil::SourceLocation()):
m_type(_type),
- m_location(_location)
+ m_location(std::move(_location))
{
if (m_type == Operation)
m_instruction = Instruction(uint8_t(_data));
else
- m_data = std::make_shared<u256>(_data);
+ m_data = std::make_shared<u256>(std::move(_data));
}
+ AssemblyItem(AssemblyItem const&) = default;
+ AssemblyItem(AssemblyItem&&) = default;
+ AssemblyItem& operator=(AssemblyItem const&) = default;
+ AssemblyItem& operator=(AssemblyItem&&) = default;
AssemblyItem tag() const { assertThrow(m_type == PushTag || m_type == Tag, Exception, ""); return AssemblyItem(Tag, data()); }
AssemblyItem pushTag() const { assertThrow(m_type == PushTag || m_type == Tag, Exception, ""); return AssemblyItem(PushTag, data()); }
@@ -114,6 +118,13 @@ public:
return data() < _other.data();
}
+ /// Shortcut that avoids constructing an AssemblyItem just to perform the comparison.
+ bool operator==(Instruction _instr) const
+ {
+ return type() == Operation && instruction() == _instr;
+ }
+ bool operator!=(Instruction _instr) const { return !operator==(_instr); }
+
/// @returns an upper bound for the number of bytes required by this item, assuming that
/// the value of a jump tag takes @a _addressLength bytes.
unsigned bytesRequired(unsigned _addressLength) const;
diff --git a/libevmasm/PeepholeOptimiser.cpp b/libevmasm/PeepholeOptimiser.cpp
index 6d8e1df6..e211026b 100644
--- a/libevmasm/PeepholeOptimiser.cpp
+++ b/libevmasm/PeepholeOptimiser.cpp
@@ -160,8 +160,7 @@ struct CommutativeSwap: SimplePeepholeOptimizerMethod<CommutativeSwap, 2>
{
// Remove SWAP1 if following instruction is commutative
if (
- _swap.type() == Operation &&
- _swap.instruction() == Instruction::SWAP1 &&
+ _swap == Instruction::SWAP1 &&
SemanticInformation::isCommutativeOperation(_op)
)
{
@@ -177,7 +176,7 @@ struct SwapComparison: SimplePeepholeOptimizerMethod<SwapComparison, 2>
{
static bool applySimple(AssemblyItem const& _swap, AssemblyItem const& _op, std::back_insert_iterator<AssemblyItems> _out)
{
- map<Instruction, Instruction> swappableOps{
+ static map<Instruction, Instruction> const swappableOps{
{ Instruction::LT, Instruction::GT },
{ Instruction::GT, Instruction::LT },
{ Instruction::SLT, Instruction::SGT },
@@ -185,8 +184,7 @@ struct SwapComparison: SimplePeepholeOptimizerMethod<SwapComparison, 2>
};
if (
- _swap.type() == Operation &&
- _swap.instruction() == Instruction::SWAP1 &&
+ _swap == Instruction::SWAP1 &&
_op.type() == Operation &&
swappableOps.count(_op.instruction())
)
diff --git a/libevmasm/SemanticInformation.cpp b/libevmasm/SemanticInformation.cpp
index 78f3c9c7..2a24a27e 100644
--- a/libevmasm/SemanticInformation.cpp
+++ b/libevmasm/SemanticInformation.cpp
@@ -108,7 +108,7 @@ bool SemanticInformation::isSwapInstruction(AssemblyItem const& _item)
bool SemanticInformation::isJumpInstruction(AssemblyItem const& _item)
{
- return _item == AssemblyItem(Instruction::JUMP) || _item == AssemblyItem(Instruction::JUMPI);
+ return _item == Instruction::JUMP || _item == Instruction::JUMPI;
}
bool SemanticInformation::altersControlFlow(AssemblyItem const& _item)
diff --git a/libsolidity/CMakeLists.txt b/libsolidity/CMakeLists.txt
index 389f94bd..8c2ab347 100644
--- a/libsolidity/CMakeLists.txt
+++ b/libsolidity/CMakeLists.txt
@@ -104,7 +104,6 @@ set(sources
find_package(Z3 QUIET)
if (${Z3_FOUND})
- include_directories(${Z3_INCLUDE_DIR})
add_definitions(-DHAVE_Z3)
message("Z3 SMT solver found. This enables optional SMT checking with Z3.")
set(z3_SRCS formal/Z3Interface.cpp formal/Z3Interface.h)
@@ -114,7 +113,6 @@ endif()
find_package(CVC4 QUIET)
if (${CVC4_FOUND})
- include_directories(${CVC4_INCLUDE_DIR})
add_definitions(-DHAVE_CVC4)
message("CVC4 SMT solver found. This enables optional SMT checking with CVC4.")
set(cvc4_SRCS formal/CVC4Interface.cpp formal/CVC4Interface.h)
@@ -131,9 +129,9 @@ add_library(solidity ${sources} ${z3_SRCS} ${cvc4_SRCS})
target_link_libraries(solidity PUBLIC yul evmasm langutil devcore ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY})
if (${Z3_FOUND})
- target_link_libraries(solidity PUBLIC ${Z3_LIBRARY})
+ target_link_libraries(solidity PUBLIC Z3::Z3)
endif()
if (${CVC4_FOUND})
- target_link_libraries(solidity PUBLIC ${CVC4_LIBRARIES})
+ target_link_libraries(solidity PUBLIC CVC4::CVC4)
endif()
diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp
index 12e14864..066b5004 100644
--- a/libsolidity/analysis/SyntaxChecker.cpp
+++ b/libsolidity/analysis/SyntaxChecker.cpp
@@ -114,7 +114,7 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
vector<string> literals(_pragma.literals().begin() + 1, _pragma.literals().end());
SemVerMatchExpressionParser parser(tokens, literals);
auto matchExpression = parser.parse();
- SemVerVersion currentVersion{string(VersionString)};
+ static SemVerVersion const currentVersion{string(VersionString)};
if (!matchExpression.matches(currentVersion))
m_errorReporter.syntaxError(
_pragma.location(),
diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp
index 625a665d..adfb94bd 100644
--- a/libsolidity/interface/CompilerStack.cpp
+++ b/libsolidity/interface/CompilerStack.cpp
@@ -619,6 +619,22 @@ tuple<int, int, int, int> CompilerStack::positionFromSourceLocation(SourceLocati
return make_tuple(++startLine, ++startColumn, ++endLine, ++endColumn);
}
+
+h256 const& CompilerStack::Source::keccak256() const
+{
+ if (keccak256HashCached == h256{})
+ keccak256HashCached = dev::keccak256(scanner->source());
+ return keccak256HashCached;
+}
+
+h256 const& CompilerStack::Source::swarmHash() const
+{
+ if (swarmHashCached == h256{})
+ swarmHashCached = dev::swarmHash(scanner->source());
+ return swarmHashCached;
+}
+
+
StringMap CompilerStack::loadMissingSources(SourceUnit const& _ast, std::string const& _sourcePath)
{
solAssert(m_stackState < ParsingSuccessful, "");
@@ -860,16 +876,13 @@ string CompilerStack::createMetadata(Contract const& _contract) const
continue;
solAssert(s.second.scanner, "Scanner not available");
- meta["sources"][s.first]["keccak256"] =
- "0x" + toHex(dev::keccak256(s.second.scanner->source()).asBytes());
+ meta["sources"][s.first]["keccak256"] = "0x" + toHex(s.second.keccak256().asBytes());
if (m_metadataLiteralSources)
meta["sources"][s.first]["content"] = s.second.scanner->source();
else
{
meta["sources"][s.first]["urls"] = Json::arrayValue;
- meta["sources"][s.first]["urls"].append(
- "bzzr://" + toHex(dev::swarmHash(s.second.scanner->source()).asBytes())
- );
+ meta["sources"][s.first]["urls"].append("bzzr://" + toHex(s.second.swarmHash().asBytes()));
}
}
meta["settings"]["optimizer"]["enabled"] = m_optimize;
@@ -896,7 +909,7 @@ string CompilerStack::createMetadata(Contract const& _contract) const
return jsonCompactPrint(meta);
}
-bytes CompilerStack::createCBORMetadata(string _metadata, bool _experimentalMode)
+bytes CompilerStack::createCBORMetadata(string const& _metadata, bool _experimentalMode)
{
bytes cborEncodedHash =
// CBOR-encoding of the key "bzzr0"
diff --git a/libsolidity/interface/CompilerStack.h b/libsolidity/interface/CompilerStack.h
index 74033170..81d5009f 100644
--- a/libsolidity/interface/CompilerStack.h
+++ b/libsolidity/interface/CompilerStack.h
@@ -261,7 +261,11 @@ private:
std::shared_ptr<langutil::Scanner> scanner;
std::shared_ptr<SourceUnit> ast;
bool isLibrary = false;
- void reset() { scanner.reset(); ast.reset(); }
+ h256 mutable keccak256HashCached;
+ h256 mutable swarmHashCached;
+ void reset() { *this = Source(); }
+ h256 const& keccak256() const;
+ h256 const& swarmHash() const;
};
/// The state per contract. Filled gradually during compilation.
@@ -315,7 +319,7 @@ private:
std::string createMetadata(Contract const& _contract) const;
/// @returns the metadata CBOR for the given serialised metadata JSON.
- static bytes createCBORMetadata(std::string _metadata, bool _experimentalMode);
+ static bytes createCBORMetadata(std::string const& _metadata, bool _experimentalMode);
/// @returns the computer source mapping string.
std::string computeSourceMapping(eth::AssemblyItems const& _items) const;
diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp
index 5be267e9..e99b1324 100644
--- a/libsolidity/interface/StandardCompiler.cpp
+++ b/libsolidity/interface/StandardCompiler.cpp
@@ -228,48 +228,97 @@ Json::Value collectEVMObject(eth::LinkerObject const& _object, string const* _so
return output;
}
-boost::optional<Json::Value> checkKeys(Json::Value const& _input, set<string> const& _keys)
+boost::optional<Json::Value> checkKeys(Json::Value const& _input, set<string> const& _keys, string const& _name)
{
+ if (!!_input && !_input.isObject())
+ return formatFatalError("JSONError", "\"" + _name + "\" must be an object");
+
for (auto const& member: _input.getMemberNames())
if (!_keys.count(member))
return formatFatalError("JSONError", "Unknown key \"" + member + "\"");
+
return boost::none;
}
boost::optional<Json::Value> checkRootKeys(Json::Value const& _input)
{
static set<string> keys{"auxiliaryInput", "language", "settings", "sources"};
- return checkKeys(_input, keys);
+ return checkKeys(_input, keys, "root");
}
-boost::optional<Json::Value> checkSourceKeys(Json::Value const& _input)
+boost::optional<Json::Value> checkSourceKeys(Json::Value const& _input, string const& _name)
{
static set<string> keys{"content", "keccak256", "urls"};
- return checkKeys(_input, keys);
+ return checkKeys(_input, keys, "sources." + _name);
}
boost::optional<Json::Value> checkAuxiliaryInputKeys(Json::Value const& _input)
{
static set<string> keys{"smtlib2responses"};
- return checkKeys(_input, keys);
+ return checkKeys(_input, keys, "auxiliaryInput");
}
boost::optional<Json::Value> checkSettingsKeys(Json::Value const& _input)
{
static set<string> keys{"evmVersion", "libraries", "metadata", "optimizer", "outputSelection", "remappings"};
- return checkKeys(_input, keys);
+ return checkKeys(_input, keys, "settings");
}
boost::optional<Json::Value> checkOptimizerKeys(Json::Value const& _input)
{
static set<string> keys{"enabled", "runs"};
- return checkKeys(_input, keys);
+ return checkKeys(_input, keys, "settings.optimizer");
}
boost::optional<Json::Value> checkMetadataKeys(Json::Value const& _input)
{
static set<string> keys{"useLiteralContent"};
- return checkKeys(_input, keys);
+ return checkKeys(_input, keys, "settings.metadata");
+}
+
+boost::optional<Json::Value> checkOutputSelection(Json::Value const& _outputSelection)
+{
+ if (!!_outputSelection && !_outputSelection.isObject())
+ return formatFatalError("JSONError", "\"settings.outputSelection\" must be an object");
+
+ for (auto const& sourceName: _outputSelection.getMemberNames())
+ {
+ auto const& sourceVal = _outputSelection[sourceName];
+
+ if (!sourceVal.isObject())
+ return formatFatalError(
+ "JSONError",
+ "\"settings.outputSelection." + sourceName + "\" must be an object"
+ );
+
+ for (auto const& contractName: sourceVal.getMemberNames())
+ {
+ auto const& contractVal = sourceVal[contractName];
+
+ if (!contractVal.isArray())
+ return formatFatalError(
+ "JSONError",
+ "\"settings.outputSelection." +
+ sourceName +
+ "." +
+ contractName +
+ "\" must be a string array"
+ );
+
+ for (auto const& output: contractVal)
+ if (!output.isString())
+ return formatFatalError(
+ "JSONError",
+ "\"settings.outputSelection." +
+ sourceName +
+ "." +
+ contractName +
+ "\" must be a string array"
+ );
+ }
+ }
+
+ return boost::none;
}
}
@@ -301,10 +350,7 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
{
string hash;
- if (!sources[sourceName].isObject())
- return formatFatalError("JSONError", "Source input is not a JSON object.");
-
- if (auto result = checkSourceKeys(sources[sourceName]))
+ if (auto result = checkSourceKeys(sources[sourceName], sourceName))
return *result;
if (sources[sourceName]["keccak256"].isString())
@@ -380,6 +426,10 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
{
Json::Value const& smtlib2Responses = auxInputs["smtlib2responses"];
if (!!smtlib2Responses)
+ {
+ if (!smtlib2Responses.isObject())
+ return formatFatalError("JSONError", "\"auxiliaryInput.smtlib2responses\" must be an object.");
+
for (auto const& hashString: smtlib2Responses.getMemberNames())
{
h256 hash;
@@ -392,8 +442,15 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
return formatFatalError("JSONError", "Invalid hex encoding of SMTLib2 auxiliary input.");
}
+ if (!smtlib2Responses[hashString].isString())
+ return formatFatalError(
+ "JSONError",
+ "\"smtlib2Responses." + hashString + "\" must be a string."
+ );
+
m_compilerStack.addSMTLib2Response(hash, smtlib2Responses[hashString].asString());
}
+ }
}
Json::Value const& settings = _input.get("settings", Json::Value());
@@ -411,11 +468,14 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
m_compilerStack.setEVMVersion(*version);
}
+ if (settings.isMember("remappings") && !settings["remappings"].isArray())
+ return formatFatalError("JSONError", "\"settings.remappings\" must be an array of strings.");
+
vector<CompilerStack::Remapping> remappings;
for (auto const& remapping: settings.get("remappings", Json::Value()))
{
if (!remapping.isString())
- return formatFatalError("JSONError", "Remapping entry must be a string.");
+ return formatFatalError("JSONError", "\"settings.remappings\" must be an array of strings");
if (auto r = CompilerStack::parseRemapping(remapping.asString()))
remappings.emplace_back(std::move(*r));
else
@@ -498,6 +558,10 @@ Json::Value StandardCompiler::compileInternal(Json::Value const& _input)
m_compilerStack.useMetadataLiteralSources(metadataSettings.get("useLiteralContent", Json::Value(false)).asBool());
Json::Value outputSelection = settings.get("outputSelection", Json::Value());
+
+ if (auto jsonError = checkOutputSelection(outputSelection))
+ return *jsonError;
+
m_compilerStack.setRequestedContractNames(requestedContractNames(outputSelection));
try
diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp
index 9de2146e..bcb28988 100644
--- a/libsolidity/parsing/Parser.cpp
+++ b/libsolidity/parsing/Parser.cpp
@@ -22,6 +22,8 @@
#include <libsolidity/parsing/Parser.h>
+#include <libsolidity/analysis/SemVerHandler.h>
+#include <libsolidity/interface/Version.h>
#include <libyul/AsmParser.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <liblangutil/ErrorReporter.h>
@@ -106,6 +108,20 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
}
}
+void Parser::parsePragmaVersion(vector<Token> const& tokens, vector<string> const& literals)
+{
+ SemVerMatchExpressionParser parser(tokens, literals);
+ auto matchExpression = parser.parse();
+ static SemVerVersion const currentVersion{string(VersionString)};
+ // FIXME: only match for major version incompatibility
+ if (!matchExpression.matches(currentVersion))
+ fatalParserError(
+ "Source file requires different compiler version (current compiler is " +
+ string(VersionString) + " - note that nightly builds are considered to be "
+ "strictly less than the released version"
+ );
+}
+
ASTPointer<PragmaDirective> Parser::parsePragmaDirective()
{
RecursionGuard recursionGuard(*this);
@@ -134,6 +150,15 @@ ASTPointer<PragmaDirective> Parser::parsePragmaDirective()
while (m_scanner->currentToken() != Token::Semicolon && m_scanner->currentToken() != Token::EOS);
nodeFactory.markEndPosition();
expectToken(Token::Semicolon);
+
+ if (literals.size() >= 2 && literals[0] == "solidity")
+ {
+ parsePragmaVersion(
+ vector<Token>(tokens.begin() + 1, tokens.end()),
+ vector<string>(literals.begin() + 1, literals.end())
+ );
+ }
+
return nodeFactory.createNode<PragmaDirective>(tokens, literals);
}
diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h
index 15852096..bf02c626 100644
--- a/libsolidity/parsing/Parser.h
+++ b/libsolidity/parsing/Parser.h
@@ -70,6 +70,7 @@ private:
///@{
///@name Parsing functions for the AST nodes
+ void parsePragmaVersion(std::vector<Token> const& tokens, std::vector<std::string> const& literals);
ASTPointer<PragmaDirective> parsePragmaDirective();
ASTPointer<ImportDirective> parseImportDirective();
ContractDefinition::ContractKind parseContractKind();
diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input.json b/test/cmdlineTests/standard_wrong_type_auxiliary_input.json
new file mode 100644
index 00000000..8d2c7593
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input.json
@@ -0,0 +1,11 @@
+{
+ "language": "Solidity",
+ "sources":
+ {
+ "A":
+ {
+ "content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
+ }
+ },
+ "auxiliaryInput": [1, 2, 3]
+}
diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input.json.exit b/test/cmdlineTests/standard_wrong_type_auxiliary_input.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input.json.stdout b/test/cmdlineTests/standard_wrong_type_auxiliary_input.json.stdout
new file mode 100644
index 00000000..046cb6d9
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input.json.stdout
@@ -0,0 +1,2 @@
+{"errors":[{"component":"general","formattedMessage":"\"auxiliaryInput\" must be an object","message":"\"auxiliaryInput\" must be an object","severity":"error","type":"JSONError"}]}
+
diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json
new file mode 100644
index 00000000..9175050f
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json
@@ -0,0 +1,20 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "fileA": {
+ "content": "contract A { }"
+ }
+ },
+ "settings": {
+ "outputSelection": {
+ "fileA": {
+ "A": [ "abi", "devdoc", "userdoc", "evm.bytecode", "evm.assembly", "evm.gasEstimates", "evm.legacyAssembly", "metadata" ],
+ "": [ "legacyAST" ]
+ }
+ }
+ },
+ "auxiliaryInput":
+ {
+ "smtlib2responses": "not an object"
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json.exit b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json.stdout b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json.stdout
new file mode 100644
index 00000000..3efaea20
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"auxiliaryInput.smtlib2responses\" must be an object.","message":"\"auxiliaryInput.smtlib2responses\" must be an object.","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json
new file mode 100644
index 00000000..aa7d451b
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json
@@ -0,0 +1,23 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "fileA": {
+ "content": "contract A { }"
+ }
+ },
+ "settings": {
+ "outputSelection": {
+ "fileA": {
+ "A": [ "abi", "devdoc", "userdoc", "evm.bytecode", "evm.assembly", "evm.gasEstimates", "evm.legacyAssembly", "metadata" ],
+ "": [ "legacyAST" ]
+ }
+ }
+ },
+ "auxiliaryInput":
+ {
+ "smtlib2responses":
+ {
+ "abc": ["not a string"]
+ }
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json.exit b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json.stdout b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json.stdout
new file mode 100644
index 00000000..a05176be
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_auxiliary_input_smtlib2responses_member.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"smtlib2Responses.abc\" must be a string.","message":"\"smtlib2Responses.abc\" must be a string.","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_metadata.json b/test/cmdlineTests/standard_wrong_type_metadata.json
new file mode 100644
index 00000000..d4dd06a1
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_metadata.json
@@ -0,0 +1,19 @@
+{
+ "language": "Solidity",
+ "sources":
+ {
+ "A":
+ {
+ "content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
+ }
+ },
+ "settings":
+ {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "evmVersion": "byzantium",
+ "metadata": ["meta1", "meta2", "meta3"]
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_metadata.json.exit b/test/cmdlineTests/standard_wrong_type_metadata.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_metadata.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_metadata.json.stdout b/test/cmdlineTests/standard_wrong_type_metadata.json.stdout
new file mode 100644
index 00000000..7b997cec
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_metadata.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"settings.metadata\" must be an object","message":"\"settings.metadata\" must be an object","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_optimizer.json b/test/cmdlineTests/standard_wrong_type_optimizer.json
new file mode 100644
index 00000000..b42ca550
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_optimizer.json
@@ -0,0 +1,18 @@
+{
+ "language": "Solidity",
+ "sources":
+ {
+ "A":
+ {
+ "content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
+ }
+ },
+ "settings":
+ {
+ "optimizer": 1,
+ "evmVersion": "byzantium",
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_optimizer.json.exit b/test/cmdlineTests/standard_wrong_type_optimizer.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_optimizer.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_optimizer.json.stdout b/test/cmdlineTests/standard_wrong_type_optimizer.json.stdout
new file mode 100644
index 00000000..d43b6470
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_optimizer.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"settings.optimizer\" must be an object","message":"\"settings.optimizer\" must be an object","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection.json b/test/cmdlineTests/standard_wrong_type_output_selection.json
new file mode 100644
index 00000000..a7b615d1
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection.json
@@ -0,0 +1,11 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "fileA": {
+ "content": "contract A { }"
+ }
+ },
+ "settings": {
+ "outputSelection": "not an object"
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection.json.exit b/test/cmdlineTests/standard_wrong_type_output_selection.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection.json.stdout b/test/cmdlineTests/standard_wrong_type_output_selection.json.stdout
new file mode 100644
index 00000000..39e74882
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"settings.outputSelection\" must be an object","message":"\"settings.outputSelection\" must be an object","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_contract.json b/test/cmdlineTests/standard_wrong_type_output_selection_contract.json
new file mode 100644
index 00000000..9840a97e
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection_contract.json
@@ -0,0 +1,16 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "fileA": {
+ "content": "contract A { }"
+ }
+ },
+ "settings": {
+ "outputSelection": {
+ "fileA": {
+ "A": "it's a contract, but not an array!",
+ "": [ "legacyAST" ]
+ }
+ }
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_contract.json.exit b/test/cmdlineTests/standard_wrong_type_output_selection_contract.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection_contract.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_contract.json.stdout b/test/cmdlineTests/standard_wrong_type_output_selection_contract.json.stdout
new file mode 100644
index 00000000..a4ba320e
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection_contract.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"settings.outputSelection.fileA.A\" must be a string array","message":"\"settings.outputSelection.fileA.A\" must be a string array","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_file.json b/test/cmdlineTests/standard_wrong_type_output_selection_file.json
new file mode 100644
index 00000000..7ab12ba8
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection_file.json
@@ -0,0 +1,13 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "fileA": {
+ "content": "contract A { }"
+ }
+ },
+ "settings": {
+ "outputSelection": {
+ "fileA": "awesome file!"
+ }
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_file.json.exit b/test/cmdlineTests/standard_wrong_type_output_selection_file.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection_file.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_file.json.stdout b/test/cmdlineTests/standard_wrong_type_output_selection_file.json.stdout
new file mode 100644
index 00000000..8874e636
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection_file.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"settings.outputSelection.fileA\" must be an object","message":"\"settings.outputSelection.fileA\" must be an object","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_output.json b/test/cmdlineTests/standard_wrong_type_output_selection_output.json
new file mode 100644
index 00000000..3e5cd661
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection_output.json
@@ -0,0 +1,16 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "fileA": {
+ "content": "contract A { }"
+ }
+ },
+ "settings": {
+ "outputSelection": {
+ "fileA": {
+ "A": [ 1, 2, 3 ,4],
+ "": [ "legacyAST" ]
+ }
+ }
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_output.json.exit b/test/cmdlineTests/standard_wrong_type_output_selection_output.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection_output.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_output_selection_output.json.stdout b/test/cmdlineTests/standard_wrong_type_output_selection_output.json.stdout
new file mode 100644
index 00000000..a4ba320e
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_output_selection_output.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"settings.outputSelection.fileA.A\" must be a string array","message":"\"settings.outputSelection.fileA.A\" must be a string array","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_remappings.json b/test/cmdlineTests/standard_wrong_type_remappings.json
new file mode 100644
index 00000000..1436e014
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_remappings.json
@@ -0,0 +1,17 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "fileA": {
+ "content": "contract A { }"
+ }
+ },
+ "settings": {
+ "outputSelection": {
+ "fileA": {
+ "A": [ "abi", "devdoc", "userdoc", "evm.bytecode", "evm.assembly", "evm.gasEstimates", "evm.legacyAssembly", "metadata" ],
+ "": [ "legacyAST" ]
+ }
+ },
+ "remappings": "not an object"
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_remappings.json.exit b/test/cmdlineTests/standard_wrong_type_remappings.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_remappings.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_remappings.json.stdout b/test/cmdlineTests/standard_wrong_type_remappings.json.stdout
new file mode 100644
index 00000000..b5e4ea5c
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_remappings.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"settings.remappings\" must be an array of strings.","message":"\"settings.remappings\" must be an array of strings.","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_remappings_entry.json b/test/cmdlineTests/standard_wrong_type_remappings_entry.json
new file mode 100644
index 00000000..c96611f3
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_remappings_entry.json
@@ -0,0 +1,17 @@
+{
+ "language": "Solidity",
+ "sources": {
+ "fileA": {
+ "content": "contract A { }"
+ }
+ },
+ "settings": {
+ "outputSelection": {
+ "fileA": {
+ "A": [ "abi", "devdoc", "userdoc", "evm.bytecode", "evm.assembly", "evm.gasEstimates", "evm.legacyAssembly", "metadata" ],
+ "": [ "legacyAST" ]
+ }
+ },
+ "remappings": [1, 2 ,3 ,4]
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_remappings_entry.json.exit b/test/cmdlineTests/standard_wrong_type_remappings_entry.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_remappings_entry.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_remappings_entry.json.stdout b/test/cmdlineTests/standard_wrong_type_remappings_entry.json.stdout
new file mode 100644
index 00000000..0fc71ded
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_remappings_entry.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"settings.remappings\" must be an array of strings","message":"\"settings.remappings\" must be an array of strings","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_root.json b/test/cmdlineTests/standard_wrong_type_root.json
new file mode 100644
index 00000000..4763607a
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_root.json
@@ -0,0 +1 @@
+["abc"]
diff --git a/test/cmdlineTests/standard_wrong_type_root.json.exit b/test/cmdlineTests/standard_wrong_type_root.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_root.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_root.json.stdout b/test/cmdlineTests/standard_wrong_type_root.json.stdout
new file mode 100644
index 00000000..15c12e77
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_root.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"Input is not a JSON object.","message":"Input is not a JSON object.","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_settings.json b/test/cmdlineTests/standard_wrong_type_settings.json
new file mode 100644
index 00000000..7cdb0881
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_settings.json
@@ -0,0 +1,23 @@
+{
+ "language": "Solidity",
+ "sources":
+ {
+ "A":
+ {
+ "content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
+ }
+ },
+ "settings":
+ [
+ {
+ "optimizer": {
+ "enabled": true,
+ "runs": 200
+ },
+ "evmVersion": "byzantium",
+ "metadata": {
+ "useLiteralContent": true
+ }
+ }
+ ]
+}
diff --git a/test/cmdlineTests/standard_wrong_type_settings.json.exit b/test/cmdlineTests/standard_wrong_type_settings.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_settings.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_settings.json.stdout b/test/cmdlineTests/standard_wrong_type_settings.json.stdout
new file mode 100644
index 00000000..c78c6086
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_settings.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"settings\" must be an object","message":"\"settings\" must be an object","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_source.json b/test/cmdlineTests/standard_wrong_type_source.json
new file mode 100644
index 00000000..d58504fe
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_source.json
@@ -0,0 +1,12 @@
+{
+ "language": "Solidity",
+ "sources":
+ {
+ "A": "not an object :o",
+ "B": [1, 2, 3],
+ "C":
+ {
+ "content": "pragma solidity >=0.0; contract C { function f() public pure {} }"
+ }
+ }
+}
diff --git a/test/cmdlineTests/standard_wrong_type_source.json.exit b/test/cmdlineTests/standard_wrong_type_source.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_source.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_source.json.stdout b/test/cmdlineTests/standard_wrong_type_source.json.stdout
new file mode 100644
index 00000000..98fe32fd
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_source.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"sources.A\" must be an object","message":"\"sources.A\" must be an object","severity":"error","type":"JSONError"}]}
diff --git a/test/cmdlineTests/standard_wrong_type_sources.json b/test/cmdlineTests/standard_wrong_type_sources.json
new file mode 100644
index 00000000..76e1ae7d
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_sources.json
@@ -0,0 +1,4 @@
+{
+ "language": "Solidity",
+ "sources": ["source1", "source2", "source3"]
+}
diff --git a/test/cmdlineTests/standard_wrong_type_sources.json.exit b/test/cmdlineTests/standard_wrong_type_sources.json.exit
new file mode 100644
index 00000000..573541ac
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_sources.json.exit
@@ -0,0 +1 @@
+0
diff --git a/test/cmdlineTests/standard_wrong_type_sources.json.stdout b/test/cmdlineTests/standard_wrong_type_sources.json.stdout
new file mode 100644
index 00000000..ac6c613f
--- /dev/null
+++ b/test/cmdlineTests/standard_wrong_type_sources.json.stdout
@@ -0,0 +1 @@
+{"errors":[{"component":"general","formattedMessage":"\"sources\" is not a JSON object.","message":"\"sources\" is not a JSON object.","severity":"error","type":"JSONError"}]}
diff --git a/test/libsolidity/AnalysisFramework.cpp b/test/libsolidity/AnalysisFramework.cpp
index 8a72f996..abeecd32 100644
--- a/test/libsolidity/AnalysisFramework.cpp
+++ b/test/libsolidity/AnalysisFramework.cpp
@@ -52,7 +52,7 @@ AnalysisFramework::parseAnalyseAndReturnError(
m_compiler.setEVMVersion(dev::test::Options::get().evmVersion());
if (!m_compiler.parse())
{
- BOOST_ERROR("Parsing contract failed in analysis test suite:" + formatErrors());
+ BOOST_FAIL("Parsing contract failed in analysis test suite:" + formatErrors());
}
m_compiler.analyze();
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 75726027..774f67fe 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -376,18 +376,6 @@ BOOST_AUTO_TEST_CASE(warn_nonpresent_pragma)
BOOST_CHECK(searchErrorMessage(*sourceAndError.second.front(), "Source file does not specify required compiler version!"));
}
-BOOST_AUTO_TEST_CASE(unsatisfied_version)
-{
- char const* text = R"(
- pragma solidity ^99.99.0;
- )";
- auto sourceAndError = parseAnalyseAndReturnError(text, false, false, false);
- BOOST_REQUIRE(!sourceAndError.second.empty());
- BOOST_REQUIRE(!!sourceAndError.first);
- BOOST_CHECK(sourceAndError.second.front()->type() == Error::Type::SyntaxError);
- BOOST_CHECK(searchErrorMessage(*sourceAndError.second.front(), "Source file requires different compiler version"));
-}
-
BOOST_AUTO_TEST_CASE(returndatasize_as_variable)
{
char const* text = R"(
diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp
index d86d3d39..a33c6134 100644
--- a/test/libsolidity/SolidityParser.cpp
+++ b/test/libsolidity/SolidityParser.cpp
@@ -113,6 +113,23 @@ while(0)
BOOST_AUTO_TEST_SUITE(SolidityParser)
+BOOST_AUTO_TEST_CASE(unsatisfied_version)
+{
+ char const* text = R"(
+ pragma solidity ^99.99.0;
+ )";
+ CHECK_PARSE_ERROR(text, "Source file requires different compiler version");
+}
+
+BOOST_AUTO_TEST_CASE(unsatisfied_version_followed_by_invalid_syntax)
+{
+ char const* text = R"(
+ pragma solidity ^99.99.0;
+ this is surely invalid
+ )";
+ CHECK_PARSE_ERROR(text, "Source file requires different compiler version");
+}
+
BOOST_AUTO_TEST_CASE(function_natspec_documentation)
{
char const* text = R"(