aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt30
-rw-r--r--test/ExecutionFramework.h2
-rw-r--r--test/Options.cpp (renamed from test/TestHelper.cpp)25
-rw-r--r--test/Options.h (renamed from test/TestHelper.h)2
-rw-r--r--test/RPCSession.cpp8
-rw-r--r--test/boostTest.cpp9
-rwxr-xr-xtest/cmdlineTests.sh6
-rw-r--r--test/libdevcore/Checksum.cpp2
-rw-r--r--test/libdevcore/IndentedWriter.cpp2
-rw-r--r--test/libdevcore/JSON.cpp2
-rw-r--r--test/libdevcore/StringUtils.cpp2
-rw-r--r--test/libdevcore/SwarmHash.cpp2
-rw-r--r--test/libdevcore/UTF8.cpp2
-rw-r--r--test/libdevcore/Whiskers.cpp2
-rw-r--r--test/libevmasm/Optimiser.cpp116
-rw-r--r--test/libevmasm/SourceLocation.cpp2
-rw-r--r--test/libjulia/Common.cpp2
-rw-r--r--test/libjulia/CommonSubexpression.cpp102
-rw-r--r--test/libjulia/Parser.cpp2
-rw-r--r--test/liblll/Compiler.cpp2
-rw-r--r--test/liblll/EndToEndTest.cpp2
-rw-r--r--test/libsolidity/ABIDecoderTests.cpp83
-rw-r--r--test/libsolidity/ASTJSON.cpp228
-rw-r--r--test/libsolidity/ASTLegacyJSON.cpp324
-rw-r--r--test/libsolidity/AnalysisFramework.cpp30
-rw-r--r--test/libsolidity/AnalysisFramework.h7
-rw-r--r--test/libsolidity/Assembly.cpp23
-rw-r--r--test/libsolidity/FormattedScope.h68
-rw-r--r--test/libsolidity/GasMeter.cpp13
-rw-r--r--test/libsolidity/Imports.cpp2
-rw-r--r--test/libsolidity/InlineAssembly.cpp4
-rw-r--r--test/libsolidity/JSONCompiler.cpp16
-rw-r--r--test/libsolidity/Metadata.cpp4
-rw-r--r--test/libsolidity/SMTChecker.cpp138
-rw-r--r--test/libsolidity/SemVerMatcher.cpp2
-rw-r--r--test/libsolidity/SolidityABIJSON.cpp2
-rw-r--r--test/libsolidity/SolidityCompiler.cpp60
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp1077
-rw-r--r--test/libsolidity/SolidityExpressionCompiler.cpp11
-rw-r--r--test/libsolidity/SolidityNameAndTypeResolution.cpp1271
-rw-r--r--test/libsolidity/SolidityNatspecJSON.cpp2
-rw-r--r--test/libsolidity/SolidityOptimizer.cpp64
-rw-r--r--test/libsolidity/SolidityParser.cpp46
-rw-r--r--test/libsolidity/SolidityTypes.cpp1
-rw-r--r--test/libsolidity/StandardCompiler.cpp21
-rw-r--r--test/libsolidity/SyntaxTest.cpp283
-rw-r--r--test/libsolidity/SyntaxTest.h91
-rw-r--r--test/libsolidity/ViewPureChecker.cpp33
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/array_length_cannot_be_constant_function_parameter.sol7
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_function.sol8
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_struct.sol7
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/can_be_recursive_constant.sol6
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/cannot_be_function.sol6
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/cannot_be_function_call.sol7
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/complex_cyclic_constant.sol10
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/const_cannot_be_fractional.sol6
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/constant_var.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/cyclic_constant.sol8
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/inline_array.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/invalid_expression_1.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/invalid_expression_2.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/invalid_expression_3.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/invalid_expression_4.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/invalid_expression_5.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/non_integer_constant_var.sol6
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/not_convertible_to_integer.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/parentheses.sol25
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/pure_functions.sol6
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/too_large.sol5
-rw-r--r--test/libsolidity/syntaxTests/arrayLength/tuples.sol5
-rw-r--r--test/libsolidity/syntaxTests/constants/addmod_mulmod_rational.sol7
-rw-r--r--test/libsolidity/syntaxTests/constants/addmod_zero.sol11
-rw-r--r--test/libsolidity/syntaxTests/constants/cyclic_dependency_1.sol5
-rw-r--r--test/libsolidity/syntaxTests/constants/cyclic_dependency_2.sol10
-rw-r--r--test/libsolidity/syntaxTests/constants/cyclic_dependency_3.sol11
-rw-r--r--test/libsolidity/syntaxTests/constants/cyclic_dependency_4.sol6
-rw-r--r--test/libsolidity/syntaxTests/constants/division_by_zero.sol9
-rw-r--r--test/libsolidity/syntaxTests/constants/mod_div_rational.sol6
-rw-r--r--test/libsolidity/syntaxTests/constants/mod_zero.sol9
-rw-r--r--test/libsolidity/syntaxTests/constants/mulmod_zero.sol11
-rw-r--r--test/libsolidity/syntaxTests/constants/pure_non_rational.sol11
-rw-r--r--test/libsolidity/syntaxTests/constructor_this.sol12
-rw-r--r--test/libsolidity/syntaxTests/docstring_empty_description.sol6
-rw-r--r--test/libsolidity/syntaxTests/double_stateVariable_declaration.sol6
-rw-r--r--test/libsolidity/syntaxTests/double_variable_declaration.sol8
-rw-r--r--test/libsolidity/syntaxTests/double_variable_declaration_050.sol11
-rw-r--r--test/libsolidity/syntaxTests/empty_struct.sol5
-rw-r--r--test/libsolidity/syntaxTests/empty_struct_050.sol6
-rw-r--r--test/libsolidity/syntaxTests/functionCalls/arbitrary_parameters_but_restricted_first_type.sol13
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol8
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol6
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol17
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol10
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_type_public_variable.sol11
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type.sol6
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol11
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol8
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_internal_public_variable.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol6
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_types_internal_visibility_error.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_types_variable_visibility.sol9
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol8
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol6
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol4
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol9
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/private_function_type.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/public_function_type.sol7
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol23
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol5
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol5
-rw-r--r--test/libsolidity/syntaxTests/inheritance/allow_empty_duplicated_super_constructor_call.sol2
-rw-r--r--test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses.sol7
-rw-r--r--test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses_V050.sol9
-rw-r--r--test/libsolidity/syntaxTests/inheritance/base_arguments_multiple_inheritance.sol9
-rw-r--r--test/libsolidity/syntaxTests/inheritance/base_arguments_no_parentheses.sol5
-rw-r--r--test/libsolidity/syntaxTests/inheritance/disallow_modifier_style_without_parentheses.sol4
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/ancestor.sol5
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/ancestor_V050.sol7
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base.sol4
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_V050.sol6
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi.sol7
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor.sol6
-rw-r--r--test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor_modifier_style.sol6
-rw-r--r--test/libsolidity/syntaxTests/inheritance/too_few_base_arguments.sol10
-rw-r--r--test/libsolidity/syntaxTests/literalOperations/division_by_zero.sol5
-rw-r--r--test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex.sol5
-rw-r--r--test/libsolidity/syntaxTests/literalOperations/mod_zero.sol5
-rw-r--r--test/libsolidity/syntaxTests/literalOperations/mod_zero_complex.sol5
-rw-r--r--test/libsolidity/syntaxTests/literal_comparisons.sol7
-rw-r--r--test/libsolidity/syntaxTests/modifiers/base_constructor_double_invocation.sol7
-rw-r--r--test/libsolidity/syntaxTests/modifiers/constructor_call_invalid_arg_count.sol9
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_double_invocation.sol4
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_invocation.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol4
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol7
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_parameters.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/function_overrides_modifier.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/illegal_modifier_override.sol4
-rw-r--r--test/libsolidity/syntaxTests/modifiers/invalid_function_modifier_type.sol6
-rw-r--r--test/libsolidity/syntaxTests/modifiers/legal_modifier_override.sol2
-rw-r--r--test/libsolidity/syntaxTests/modifiers/modifier_overrides_function.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/modifier_returns_value.sol6
-rw-r--r--test/libsolidity/syntaxTests/modifiers/modifier_without_underscore.sol5
-rw-r--r--test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_050.sol10
-rw-r--r--test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_no_parser_error.sol13
-rw-r--r--test/libsolidity/syntaxTests/more_than_256_declarationerrors.sol524
-rw-r--r--test/libsolidity/syntaxTests/more_than_256_syntaxerrors.sol524
-rw-r--r--test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol28
-rw-r--r--test/libsolidity/syntaxTests/parsing/constructor_super.sol10
-rw-r--r--test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol5
-rw-r--r--test/libsolidity/syntaxTests/parsing/return_var.sol25
-rw-r--r--test/libsolidity/syntaxTests/parsing/smoke_test.sol4
-rw-r--r--test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol25
-rw-r--r--test/libsolidity/syntaxTests/parsing/var_storage_var.sol5
-rw-r--r--test/libsolidity/syntaxTests/scoping/double_function_declaration.sol6
-rw-r--r--test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol8
-rw-r--r--test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol10
-rw-r--r--test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol8
-rw-r--r--test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol10
-rw-r--r--test/libsolidity/syntaxTests/scoping/name_shadowing.sol6
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping.sol11
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_activation.sol9
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol6
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_for.sol8
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_for2.sol7
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_for3.sol11
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol10
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_old.sol6
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_self_use.sol5
-rw-r--r--test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol8
-rw-r--r--test/libsolidity/syntaxTests/signed_rational_modulus.sol8
-rw-r--r--test/libsolidity/syntaxTests/smoke_test.sol6
-rw-r--r--test/libsolidity/syntaxTests/specialFunctions/abi_encode_structs.sol17
-rw-r--r--test/libsolidity/syntaxTests/specialFunctions/abi_encode_structs_abiv2.sol18
-rw-r--r--test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol11
-rw-r--r--test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_special_types.sol13
-rw-r--r--test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_structs.sol13
-rw-r--r--test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_structs_abiv2.sol16
-rw-r--r--test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_types.sol17
-rw-r--r--test/libsolidity/syntaxTests/specialFunctions/types_without_encoding_problems.sol9
-rw-r--r--test/libsolidity/syntaxTests/structs/recursion/multi_struct_composition.sol15
-rw-r--r--test/libsolidity/syntaxTests/structs/recursion/parallel_structs.sol15
-rw-r--r--test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs.sol7
-rw-r--r--test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs2.sol7
-rw-r--r--test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs3.sol8
-rw-r--r--test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive.sol8
-rw-r--r--test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive.sol12
-rw-r--r--test/libsolidity/syntaxTests/structs/recursion/struct_definition_not_really_recursive.sol4
-rw-r--r--test/libsolidity/syntaxTests/structs/recursion/struct_definition_recursion_via_mapping.sol7
-rw-r--r--test/libsolidity/syntaxTests/tight_packing_literals.sol25
-rw-r--r--test/libsolidity/syntaxTests/tight_packing_literals_fine.sol11
-rw-r--r--test/libsolidity/syntaxTests/types/rational_number_array_index_limit.sol5
-rw-r--r--test/libsolidity/syntaxTests/types/rational_number_bitshift_limit.sol13
-rw-r--r--test/libsolidity/syntaxTests/types/rational_number_div_limit.sol9
-rw-r--r--test/libsolidity/syntaxTests/types/rational_number_exp_limit.sol50
-rw-r--r--test/libsolidity/syntaxTests/types/rational_number_literal_limit_1.sol9
-rw-r--r--test/libsolidity/syntaxTests/types/rational_number_literal_limit_2.sol9
-rw-r--r--test/libsolidity/syntaxTests/types/rational_number_literal_limit_3.sol9
-rw-r--r--test/libsolidity/syntaxTests/types/rational_number_mul_limit.sol9
-rw-r--r--test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode.sol8
-rw-r--r--test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode_arguments.sol36
-rw-r--r--test/libsolidity/syntaxTests/virtualLookup/modifiers_in_libraries.sol14
-rw-r--r--test/libsolidity/syntaxTests/visibility/external_library_function.sol14
-rw-r--r--test/libsolidity/syntaxTests/visibility/interface/function_default.sol6
-rw-r--r--test/libsolidity/syntaxTests/visibility/interface/function_default050.sol7
-rw-r--r--test/libsolidity/syntaxTests/visibility/interface/function_external050.sol5
-rw-r--r--test/libsolidity/syntaxTests/visibility/interface/function_internal.sol5
-rw-r--r--test/libsolidity/syntaxTests/visibility/interface/function_private.sol5
-rw-r--r--test/libsolidity/syntaxTests/visibility/interface/function_public.sol5
-rw-r--r--test/libsolidity/syntaxTests/visibility/interface/function_public050.sol6
-rw-r--r--test/tools/CMakeLists.txt5
-rw-r--r--test/tools/fuzzer.cpp (renamed from test/fuzzer.cpp)0
-rw-r--r--test/tools/isoltest.cpp396
225 files changed, 5664 insertions, 1493 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index f36ad4c5..522856cc 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,9 +1,27 @@
-file(GLOB_RECURSE sources "*.cpp")
-list(REMOVE_ITEM sources "${CMAKE_CURRENT_SOURCE_DIR}/fuzzer.cpp")
-file(GLOB_RECURSE headers "*.h")
+file(GLOB sources "*.cpp")
+file(GLOB headers "*.h")
-add_executable(soltest ${sources} ${headers})
+file(GLOB contracts_sources "contracts/*.cpp")
+file(GLOB contracts_headers "contracts/*.h")
+file(GLOB libdevcore_sources "libdevcore/*.cpp")
+file(GLOB libdevcore_headers "libdevcore/*.h")
+file(GLOB libevmasm_sources "libevmasm/*.cpp")
+file(GLOB libevmasm_headers "libevmasm/*.h")
+file(GLOB libjulia_sources "libjulia/*.cpp")
+file(GLOB libjulia_headers "libjulia/*.h")
+file(GLOB liblll_sources "liblll/*.cpp")
+file(GLOB liblll_headers "liblll/*.h")
+file(GLOB libsolidity_sources "libsolidity/*.cpp")
+file(GLOB libsolidity_headers "libsolidity/*.h")
+
+add_executable(soltest ${sources} ${headers}
+ ${contracts_sources} ${contracts_headers}
+ ${libdevcore_sources} ${libdevcore_headers}
+ ${libevmasm_sources} ${libevmasm_headers}
+ ${libjulia_sources} ${libjulia_headers}
+ ${liblll_sources} ${liblll_headers}
+ ${libsolidity_sources} ${libsolidity_headers}
+)
target_link_libraries(soltest PRIVATE libsolc solidity lll evmasm devcore ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
-add_executable(solfuzzer fuzzer.cpp)
-target_link_libraries(solfuzzer PRIVATE libsolc evmasm ${Boost_PROGRAM_OPTIONS_LIBRARIES})
+add_subdirectory(tools)
diff --git a/test/ExecutionFramework.h b/test/ExecutionFramework.h
index a7971b81..ee8da322 100644
--- a/test/ExecutionFramework.h
+++ b/test/ExecutionFramework.h
@@ -22,7 +22,7 @@
#pragma once
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <test/RPCSession.h>
#include <libsolidity/interface/EVMVersion.h>
diff --git a/test/TestHelper.cpp b/test/Options.cpp
index e0d4423d..ff4a7c98 100644
--- a/test/TestHelper.cpp
+++ b/test/Options.cpp
@@ -19,9 +19,10 @@
* @date 2014
*/
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libsolidity/interface/EVMVersion.h>
+#include <libsolidity/interface/Exceptions.h>
#include <boost/test/framework.hpp>
@@ -43,6 +44,11 @@ Options::Options()
ipcPath = suite.argv[i + 1];
i++;
}
+ else if (string(suite.argv[i]) == "--testpath" && i + 1 < suite.argc)
+ {
+ testPath = suite.argv[i + 1];
+ i++;
+ }
else if (string(suite.argv[i]) == "--optimize")
optimize = true;
else if (string(suite.argv[i]) == "--evm-version")
@@ -60,6 +66,23 @@ Options::Options()
if (!disableIPC && ipcPath.empty())
if (auto path = getenv("ETH_TEST_IPC"))
ipcPath = path;
+
+ if (testPath.empty())
+ if (auto path = getenv("ETH_TEST_PATH"))
+ testPath = path;
+}
+
+void Options::validate() const
+{
+ solAssert(
+ !dev::test::Options::get().testPath.empty(),
+ "No test path specified. The --testpath argument is required."
+ );
+ if (!disableIPC)
+ solAssert(
+ !dev::test::Options::get().ipcPath.empty(),
+ "No ipc path specified. The --ipcpath argument is required, unless --no-ipc is used."
+ );
}
dev::solidity::EVMVersion Options::evmVersion() const
diff --git a/test/TestHelper.h b/test/Options.h
index 8c2eec36..9bc69876 100644
--- a/test/TestHelper.h
+++ b/test/Options.h
@@ -35,11 +35,13 @@ namespace test
struct Options: boost::noncopyable
{
std::string ipcPath;
+ boost::filesystem::path testPath;
bool showMessages = false;
bool optimize = false;
bool disableIPC = false;
bool disableSMT = false;
+ void validate() const;
solidity::EVMVersion evmVersion() const;
static Options const& get();
diff --git a/test/RPCSession.cpp b/test/RPCSession.cpp
index 54871057..f4eae865 100644
--- a/test/RPCSession.cpp
+++ b/test/RPCSession.cpp
@@ -21,7 +21,7 @@
#include <test/RPCSession.h>
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libsolidity/interface/EVMVersion.h>
@@ -226,6 +226,8 @@ void RPCSession::test_setChainParams(vector<string> const& _accounts)
forks += "\"EIP158ForkBlock\": \"0x00\",\n";
if (test::Options::get().evmVersion() >= solidity::EVMVersion::byzantium())
forks += "\"byzantiumForkBlock\": \"0x00\",\n";
+ if (test::Options::get().evmVersion() >= solidity::EVMVersion::constantinople())
+ forks += "\"constantinopleForkBlock\": \"0x00\",\n";
static string const c_configString = R"(
{
"sealEngine": "NoProof",
@@ -337,7 +339,9 @@ Json::Value RPCSession::rpcCall(string const& _methodName, vector<string> const&
BOOST_TEST_MESSAGE("Reply: " + reply);
Json::Value result;
- BOOST_REQUIRE(jsonParseStrict(reply, result));
+ string errorMsg;
+ if (!jsonParseStrict(reply, result, &errorMsg))
+ BOOST_REQUIRE_MESSAGE(false, errorMsg);
if (result.isMember("error"))
{
diff --git a/test/boostTest.cpp b/test/boostTest.cpp
index a3cc51c5..f16973b5 100644
--- a/test/boostTest.cpp
+++ b/test/boostTest.cpp
@@ -35,7 +35,8 @@
#pragma GCC diagnostic pop
-#include <test/TestHelper.h>
+#include <test/Options.h>
+#include <test/libsolidity/SyntaxTest.h>
using namespace boost::unit_test;
@@ -54,6 +55,12 @@ test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] )
{
master_test_suite_t& master = framework::master_test_suite();
master.p_name.value = "SolidityTests";
+ dev::test::Options::get().validate();
+ solAssert(dev::solidity::test::SyntaxTest::registerTests(
+ master,
+ dev::test::Options::get().testPath / "libsolidity",
+ "syntaxTests"
+ ) > 0, "no syntax tests found");
if (dev::test::Options::get().disableIPC)
{
for (auto suite: {
diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh
index e86e0ad4..1137c7b0 100755
--- a/test/cmdlineTests.sh
+++ b/test/cmdlineTests.sh
@@ -32,7 +32,7 @@ REPO_ROOT=$(cd $(dirname "$0")/.. && pwd)
echo $REPO_ROOT
SOLC="$REPO_ROOT/build/solc/solc"
-FULLARGS="--optimize --combined-json abi,asm,ast,bin,bin-runtime,clone-bin,compact-format,devdoc,hashes,interface,metadata,opcodes,srcmap,srcmap-runtime,userdoc"
+FULLARGS="--optimize --ignore-missing --combined-json abi,asm,ast,bin,bin-runtime,clone-bin,compact-format,devdoc,hashes,interface,metadata,opcodes,srcmap,srcmap-runtime,userdoc"
echo "Checking that the bug list is up to date..."
"$REPO_ROOT"/scripts/update_bugs_by_version.py
@@ -170,14 +170,14 @@ TMPDIR=$(mktemp -d)
for f in *.sol
do
set +e
- "$REPO_ROOT"/build/test/solfuzzer --quiet < "$f"
+ "$REPO_ROOT"/build/test/tools/solfuzzer --quiet < "$f"
if [ $? -ne 0 ]; then
printError "Fuzzer failed on:"
cat "$f"
exit 1
fi
- "$REPO_ROOT"/build/test/solfuzzer --without-optimizer --quiet < "$f"
+ "$REPO_ROOT"/build/test/tools/solfuzzer --without-optimizer --quiet < "$f"
if [ $? -ne 0 ]; then
printError "Fuzzer (without optimizer) failed on:"
cat "$f"
diff --git a/test/libdevcore/Checksum.cpp b/test/libdevcore/Checksum.cpp
index 4eedbd99..95066b69 100644
--- a/test/libdevcore/Checksum.cpp
+++ b/test/libdevcore/Checksum.cpp
@@ -22,7 +22,7 @@
#include <libdevcore/Exceptions.h>
-#include "../TestHelper.h"
+#include <test/Options.h>
using namespace std;
diff --git a/test/libdevcore/IndentedWriter.cpp b/test/libdevcore/IndentedWriter.cpp
index a694aa1b..916c99d0 100644
--- a/test/libdevcore/IndentedWriter.cpp
+++ b/test/libdevcore/IndentedWriter.cpp
@@ -20,7 +20,7 @@
#include <libdevcore/IndentedWriter.h>
-#include "../TestHelper.h"
+#include <test/Options.h>
using namespace std;
diff --git a/test/libdevcore/JSON.cpp b/test/libdevcore/JSON.cpp
index 39d71b42..39d958f5 100644
--- a/test/libdevcore/JSON.cpp
+++ b/test/libdevcore/JSON.cpp
@@ -21,7 +21,7 @@
#include <libdevcore/JSON.h>
-#include "../TestHelper.h"
+#include <test/Options.h>
using namespace std;
diff --git a/test/libdevcore/StringUtils.cpp b/test/libdevcore/StringUtils.cpp
index 597457cc..9ee93d02 100644
--- a/test/libdevcore/StringUtils.cpp
+++ b/test/libdevcore/StringUtils.cpp
@@ -20,7 +20,7 @@
#include <libdevcore/StringUtils.h>
-#include "../TestHelper.h"
+#include <test/Options.h>
using namespace std;
diff --git a/test/libdevcore/SwarmHash.cpp b/test/libdevcore/SwarmHash.cpp
index 1ed1da18..913586f8 100644
--- a/test/libdevcore/SwarmHash.cpp
+++ b/test/libdevcore/SwarmHash.cpp
@@ -20,7 +20,7 @@
#include <libdevcore/SwarmHash.h>
-#include "../TestHelper.h"
+#include <test/Options.h>
using namespace std;
diff --git a/test/libdevcore/UTF8.cpp b/test/libdevcore/UTF8.cpp
index 719ada72..6de4570f 100644
--- a/test/libdevcore/UTF8.cpp
+++ b/test/libdevcore/UTF8.cpp
@@ -21,7 +21,7 @@
#include <libdevcore/CommonData.h>
#include <libdevcore/UTF8.h>
-#include "../TestHelper.h"
+#include <test/Options.h>
using namespace std;
diff --git a/test/libdevcore/Whiskers.cpp b/test/libdevcore/Whiskers.cpp
index 84149173..b12acdd7 100644
--- a/test/libdevcore/Whiskers.cpp
+++ b/test/libdevcore/Whiskers.cpp
@@ -20,7 +20,7 @@
#include <libdevcore/Whiskers.h>
-#include "../TestHelper.h"
+#include <test/Options.h>
using namespace std;
diff --git a/test/libevmasm/Optimiser.cpp b/test/libevmasm/Optimiser.cpp
index e6abcb53..089be45d 100644
--- a/test/libevmasm/Optimiser.cpp
+++ b/test/libevmasm/Optimiser.cpp
@@ -20,7 +20,7 @@
* Tests for the Solidity optimizer.
*/
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libevmasm/CommonSubexpressionEliminator.h>
#include <libevmasm/PeepholeOptimiser.h>
@@ -69,8 +69,9 @@ namespace
{
AssemblyItems input = addDummyLocations(_input);
+ bool usesMsize = (find(_input.begin(), _input.end(), AssemblyItem{Instruction::MSIZE}) != _input.end());
eth::CommonSubexpressionEliminator cse(_state);
- BOOST_REQUIRE(cse.feedItems(input.begin(), input.end()) == input.end());
+ BOOST_REQUIRE(cse.feedItems(input.begin(), input.end(), usesMsize) == input.end());
AssemblyItems output = cse.getOptimizedItems();
for (AssemblyItem const& item: output)
@@ -124,7 +125,7 @@ BOOST_AUTO_TEST_CASE(cse_intermediate_swap)
Instruction::SLOAD, Instruction::SWAP1, u256(100), Instruction::EXP, Instruction::SWAP1,
Instruction::DIV, u256(0xff), Instruction::AND
};
- BOOST_REQUIRE(cse.feedItems(input.begin(), input.end()) == input.end());
+ BOOST_REQUIRE(cse.feedItems(input.begin(), input.end(), false) == input.end());
AssemblyItems output = cse.getOptimizedItems();
BOOST_CHECK(!output.empty());
}
@@ -857,6 +858,115 @@ BOOST_AUTO_TEST_CASE(peephole_pop_calldatasize)
BOOST_CHECK(items.empty());
}
+BOOST_AUTO_TEST_CASE(peephole_commutative_swap1)
+{
+ vector<Instruction> ops{
+ Instruction::ADD,
+ Instruction::MUL,
+ Instruction::EQ,
+ Instruction::AND,
+ Instruction::OR,
+ Instruction::XOR
+ };
+ for (Instruction const op: ops)
+ {
+ AssemblyItems items{
+ u256(1),
+ u256(2),
+ Instruction::SWAP1,
+ op,
+ u256(4),
+ u256(5)
+ };
+ AssemblyItems expectation{
+ u256(1),
+ u256(2),
+ op,
+ u256(4),
+ u256(5)
+ };
+ PeepholeOptimiser peepOpt(items);
+ BOOST_REQUIRE(peepOpt.optimise());
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ items.begin(), items.end(),
+ expectation.begin(), expectation.end()
+ );
+ }
+}
+
+BOOST_AUTO_TEST_CASE(peephole_noncommutative_swap1)
+{
+ // NOTE: not comprehensive
+ vector<Instruction> ops{
+ Instruction::SUB,
+ Instruction::DIV,
+ Instruction::SDIV,
+ Instruction::MOD,
+ Instruction::SMOD,
+ Instruction::EXP
+ };
+ for (Instruction const op: ops)
+ {
+ AssemblyItems items{
+ u256(1),
+ u256(2),
+ Instruction::SWAP1,
+ op,
+ u256(4),
+ u256(5)
+ };
+ AssemblyItems expectation{
+ u256(1),
+ u256(2),
+ Instruction::SWAP1,
+ op,
+ u256(4),
+ u256(5)
+ };
+ PeepholeOptimiser peepOpt(items);
+ BOOST_REQUIRE(!peepOpt.optimise());
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ items.begin(), items.end(),
+ expectation.begin(), expectation.end()
+ );
+ }
+}
+
+BOOST_AUTO_TEST_CASE(peephole_swap_comparison)
+{
+ map<Instruction, Instruction> swappableOps{
+ { Instruction::LT, Instruction::GT },
+ { Instruction::GT, Instruction::LT },
+ { Instruction::SLT, Instruction::SGT },
+ { Instruction::SGT, Instruction::SLT }
+ };
+
+ for (auto const& op: swappableOps)
+ {
+ AssemblyItems items{
+ u256(1),
+ u256(2),
+ Instruction::SWAP1,
+ op.first,
+ u256(4),
+ u256(5)
+ };
+ AssemblyItems expectation{
+ u256(1),
+ u256(2),
+ op.second,
+ u256(4),
+ u256(5)
+ };
+ PeepholeOptimiser peepOpt(items);
+ BOOST_REQUIRE(peepOpt.optimise());
+ BOOST_CHECK_EQUAL_COLLECTIONS(
+ items.begin(), items.end(),
+ expectation.begin(), expectation.end()
+ );
+ }
+}
+
BOOST_AUTO_TEST_CASE(jumpdest_removal)
{
AssemblyItems items{
diff --git a/test/libevmasm/SourceLocation.cpp b/test/libevmasm/SourceLocation.cpp
index 6889b3e6..764da3cd 100644
--- a/test/libevmasm/SourceLocation.cpp
+++ b/test/libevmasm/SourceLocation.cpp
@@ -22,7 +22,7 @@
#include <libevmasm/SourceLocation.h>
-#include "../TestHelper.h"
+#include <test/Options.h>
namespace dev
{
diff --git a/test/libjulia/Common.cpp b/test/libjulia/Common.cpp
index 41f5d320..24519b01 100644
--- a/test/libjulia/Common.cpp
+++ b/test/libjulia/Common.cpp
@@ -21,7 +21,7 @@
#include <test/libjulia/Common.h>
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libjulia/optimiser/Disambiguator.h>
diff --git a/test/libjulia/CommonSubexpression.cpp b/test/libjulia/CommonSubexpression.cpp
new file mode 100644
index 00000000..8a575c48
--- /dev/null
+++ b/test/libjulia/CommonSubexpression.cpp
@@ -0,0 +1,102 @@
+/*
+ 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/>.
+*/
+/**
+ * Unit tests for the common subexpression eliminator optimizer stage.
+ */
+
+#include <test/libjulia/Common.h>
+
+#include <libjulia/optimiser/CommonSubexpressionEliminator.h>
+
+#include <libsolidity/inlineasm/AsmPrinter.h>
+
+#include <boost/test/unit_test.hpp>
+
+#include <boost/range/adaptors.hpp>
+#include <boost/algorithm/string/join.hpp>
+
+using namespace std;
+using namespace dev;
+using namespace dev::julia;
+using namespace dev::julia::test;
+using namespace dev::solidity;
+
+
+#define CHECK(_original, _expectation)\
+do\
+{\
+ assembly::AsmPrinter p;\
+ Block b = disambiguate(_original, false);\
+ (CommonSubexpressionEliminator{})(b);\
+ string result = p(b);\
+ BOOST_CHECK_EQUAL(result, format(_expectation, false));\
+}\
+while(false)
+
+BOOST_AUTO_TEST_SUITE(IuliaCSE)
+
+BOOST_AUTO_TEST_CASE(smoke_test)
+{
+ CHECK("{ }", "{ }");
+}
+
+BOOST_AUTO_TEST_CASE(trivial)
+{
+ CHECK(
+ "{ let a := mul(1, codesize()) let b := mul(1, codesize()) }",
+ "{ let a := mul(1, codesize()) let b := a }"
+ );
+}
+
+BOOST_AUTO_TEST_CASE(non_movable_instr)
+{
+ CHECK(
+ "{ let a := mload(1) let b := mload(1) }",
+ "{ let a := mload(1) let b := mload(1) }"
+ );
+}
+
+BOOST_AUTO_TEST_CASE(non_movable_instr2)
+{
+ CHECK(
+ "{ let a := gas() let b := gas() }",
+ "{ let a := gas() let b := gas() }"
+ );
+}
+
+BOOST_AUTO_TEST_CASE(branches_if)
+{
+ CHECK(
+ "{ let b := 1 if b { b := 1 } let c := 1 }",
+ "{ let b := 1 if b { b := b } let c := 1 }"
+ );
+}
+
+BOOST_AUTO_TEST_CASE(branches_for)
+{
+ CHECK(
+ "{ let a := 1 let b := codesize()"
+ "for { } lt(1, codesize()) { mstore(1, codesize()) a := add(a, codesize()) }"
+ "{ mstore(1, codesize()) } mstore(1, codesize()) }",
+
+ "{ let a := 1 let b := codesize()"
+ "for { } lt(1, b) { mstore(1, b) a := add(a, b) }"
+ "{ mstore(1, b) } mstore(1, b) }"
+ );
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libjulia/Parser.cpp b/test/libjulia/Parser.cpp
index df905dd6..9d66658e 100644
--- a/test/libjulia/Parser.cpp
+++ b/test/libjulia/Parser.cpp
@@ -19,7 +19,7 @@
* Unit tests for parsing Julia.
*/
-#include "../TestHelper.h"
+#include <test/Options.h>
#include <test/libsolidity/ErrorCheck.h>
diff --git a/test/liblll/Compiler.cpp b/test/liblll/Compiler.cpp
index 6c6eae3f..ebdea185 100644
--- a/test/liblll/Compiler.cpp
+++ b/test/liblll/Compiler.cpp
@@ -20,7 +20,7 @@
* Unit tests for the LLL compiler.
*/
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libdevcore/FixedHash.h>
diff --git a/test/liblll/EndToEndTest.cpp b/test/liblll/EndToEndTest.cpp
index e5e70cf8..fd8099f2 100644
--- a/test/liblll/EndToEndTest.cpp
+++ b/test/liblll/EndToEndTest.cpp
@@ -21,7 +21,7 @@
*/
#include <test/liblll/ExecutionFramework.h>
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <boost/test/unit_test.hpp>
diff --git a/test/libsolidity/ABIDecoderTests.cpp b/test/libsolidity/ABIDecoderTests.cpp
index 15c04b37..beb7b5af 100644
--- a/test/libsolidity/ABIDecoderTests.cpp
+++ b/test/libsolidity/ABIDecoderTests.cpp
@@ -786,6 +786,89 @@ BOOST_AUTO_TEST_CASE(complex_struct)
}
+BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_simple)
+{
+ if (m_evmVersion == EVMVersion::homestead())
+ return;
+
+ string sourceCode = R"(
+ contract C {
+ function dyn() public returns (bytes) {
+ return "1234567890123456789012345678901234567890";
+ }
+ function f() public returns (bytes) {
+ return this.dyn();
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(0x20, 40, string("1234567890123456789012345678901234567890")));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_advanced)
+{
+ if (m_evmVersion == EVMVersion::homestead())
+ return;
+
+ string sourceCode = R"(
+ contract C {
+ function dyn() public returns (bytes a, uint b, bytes20[] c, uint d) {
+ a = "1234567890123456789012345678901234567890";
+ b = uint(-1);
+ c = new bytes20[](4);
+ c[0] = bytes20(1234);
+ c[3] = bytes20(6789);
+ d = 0x1234;
+ }
+ function f() public returns (bytes, uint, bytes20[], uint) {
+ return this.dyn();
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(
+ 0x80, u256(-1), 0xe0, 0x1234,
+ 40, string("1234567890123456789012345678901234567890"),
+ 4, u256(1234) << (8 * (32 - 20)), 0, 0, u256(6789) << (8 * (32 - 20))
+ ));
+ )
+}
+
+BOOST_AUTO_TEST_CASE(return_dynamic_types_cross_call_out_of_range)
+{
+ string sourceCode = R"(
+ contract C {
+ function dyn(uint x) public returns (bytes a) {
+ assembly {
+ mstore(0, 0x20)
+ mstore(0x20, 0x21)
+ return(0, x)
+ }
+ }
+ function f(uint x) public returns (bool) {
+ this.dyn(x);
+ return true;
+ }
+ }
+ )";
+ BOTH_ENCODERS(
+ compileAndRun(sourceCode, 0, "C");
+ if (m_evmVersion == EVMVersion::homestead())
+ {
+ ABI_CHECK(callContractFunction("f(uint256)", 0x60), encodeArgs(true));
+ ABI_CHECK(callContractFunction("f(uint256)", 0x7f), encodeArgs(true));
+ }
+ else
+ {
+ ABI_CHECK(callContractFunction("f(uint256)", 0x60), encodeArgs());
+ ABI_CHECK(callContractFunction("f(uint256)", 0x61), encodeArgs(true));
+ }
+ ABI_CHECK(callContractFunction("f(uint256)", 0x80), encodeArgs(true));
+ )
+}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libsolidity/ASTJSON.cpp b/test/libsolidity/ASTJSON.cpp
index 9bf60b64..5d5b14e8 100644
--- a/test/libsolidity/ASTJSON.cpp
+++ b/test/libsolidity/ASTJSON.cpp
@@ -20,7 +20,7 @@
* Tests for the json ast output.
*/
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/interface/CompilerStack.h>
@@ -41,207 +41,62 @@ namespace test
BOOST_AUTO_TEST_SUITE(SolidityASTJSON)
-BOOST_AUTO_TEST_CASE(smoke_test)
+BOOST_AUTO_TEST_CASE(short_type_name)
{
CompilerStack c;
- c.addSource("a", "contract C {}");
+ c.addSource("a", "contract c { function f() { uint[] memory x; } }");
c.setEVMVersion(dev::test::Options::get().evmVersion());
c.parseAndAnalyze();
map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- BOOST_CHECK_EQUAL(astJson["name"], "SourceUnit");
+ Json::Value astJson = ASTJsonConverter(false, sourceIndices).toJson(c.ast("a"));
+ Json::Value varDecl = astJson["nodes"][0]["nodes"][0]["body"]["statements"][0]["declarations"][0];
+ BOOST_CHECK_EQUAL(varDecl["storageLocation"], "memory");
+ BOOST_CHECK_EQUAL(varDecl["typeDescriptions"]["typeIdentifier"], "t_array$_t_uint256_$dyn_memory_ptr");
+ BOOST_CHECK_EQUAL(varDecl["typeDescriptions"]["typeString"], "uint256[]");
}
-BOOST_AUTO_TEST_CASE(source_location)
+BOOST_AUTO_TEST_CASE(short_type_name_ref)
{
CompilerStack c;
- c.addSource("a", "contract C { function f() { var x = 2; x++; } }");
+ c.addSource("a", "contract c { function f() { uint[][] memory rows; } }");
c.setEVMVersion(dev::test::Options::get().evmVersion());
c.parseAndAnalyze();
map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- BOOST_CHECK_EQUAL(astJson["name"], "SourceUnit");
- BOOST_CHECK_EQUAL(astJson["children"][0]["name"], "ContractDefinition");
- BOOST_CHECK_EQUAL(astJson["children"][0]["children"][0]["name"], "FunctionDefinition");
- BOOST_CHECK_EQUAL(astJson["children"][0]["children"][0]["src"], "13:32:1");
+ Json::Value astJson = ASTJsonConverter(false, sourceIndices).toJson(c.ast("a"));
+ Json::Value varDecl = astJson["nodes"][0]["nodes"][0]["body"]["statements"][0]["declarations"][0];
+ BOOST_CHECK_EQUAL(varDecl["storageLocation"], "memory");
+ BOOST_CHECK_EQUAL(varDecl["typeName"]["typeDescriptions"]["typeIdentifier"], "t_array$_t_array$_t_uint256_$dyn_storage_$dyn_storage_ptr");
+ BOOST_CHECK_EQUAL(varDecl["typeName"]["typeDescriptions"]["typeString"], "uint256[][]");
}
-BOOST_AUTO_TEST_CASE(inheritance_specifier)
+BOOST_AUTO_TEST_CASE(long_type_name_binary_operation)
{
CompilerStack c;
- c.addSource("a", "contract C1 {} contract C2 is C1 {}");
+ c.addSource("a", "contract c { function f() public { uint a = 2 + 3; } }");
c.setEVMVersion(dev::test::Options::get().evmVersion());
c.parseAndAnalyze();
map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- BOOST_CHECK_EQUAL(astJson["children"][1]["attributes"]["name"], "C2");
- BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["name"], "InheritanceSpecifier");
- BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["src"], "30:2:1");
- BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["children"][0]["name"], "UserDefinedTypeName");
- BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["children"][0]["attributes"]["name"], "C1");
+ Json::Value astJson = ASTJsonConverter(false, sourceIndices).toJson(c.ast("a"));
+ Json::Value varDecl = astJson["nodes"][0]["nodes"][0]["body"]["statements"][0]["initialValue"]["commonType"];
+ BOOST_CHECK_EQUAL(varDecl["typeIdentifier"], "t_rational_5_by_1");
+ BOOST_CHECK_EQUAL(varDecl["typeString"], "int_const 5");
}
-BOOST_AUTO_TEST_CASE(using_for_directive)
+BOOST_AUTO_TEST_CASE(long_type_name_identifier)
{
CompilerStack c;
- c.addSource("a", "library L {} contract C { using L for uint; }");
+ c.addSource("a", "contract c { uint[] a; function f() public { uint[] b = a; } }");
c.setEVMVersion(dev::test::Options::get().evmVersion());
c.parseAndAnalyze();
map<string, unsigned> sourceIndices;
sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- Json::Value usingFor = astJson["children"][1]["children"][0];
- BOOST_CHECK_EQUAL(usingFor["name"], "UsingForDirective");
- BOOST_CHECK_EQUAL(usingFor["src"], "26:17:1");
- BOOST_CHECK_EQUAL(usingFor["children"][0]["name"], "UserDefinedTypeName");
- BOOST_CHECK_EQUAL(usingFor["children"][0]["attributes"]["name"], "L");
- BOOST_CHECK_EQUAL(usingFor["children"][1]["name"], "ElementaryTypeName");
- BOOST_CHECK_EQUAL(usingFor["children"][1]["attributes"]["name"], "uint");
-}
-
-BOOST_AUTO_TEST_CASE(enum_value)
-{
- CompilerStack c;
- c.addSource("a", "contract C { enum E { A, B } }");
- c.setEVMVersion(dev::test::Options::get().evmVersion());
- c.parseAndAnalyze();
- map<string, unsigned> sourceIndices;
- sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- Json::Value enumDefinition = astJson["children"][0]["children"][0];
- BOOST_CHECK_EQUAL(enumDefinition["children"][0]["name"], "EnumValue");
- BOOST_CHECK_EQUAL(enumDefinition["children"][0]["attributes"]["name"], "A");
- BOOST_CHECK_EQUAL(enumDefinition["children"][0]["src"], "22:1:1");
- BOOST_CHECK_EQUAL(enumDefinition["children"][1]["name"], "EnumValue");
- BOOST_CHECK_EQUAL(enumDefinition["children"][1]["attributes"]["name"], "B");
- BOOST_CHECK_EQUAL(enumDefinition["children"][1]["src"], "25:1:1");
-}
-
-BOOST_AUTO_TEST_CASE(modifier_definition)
-{
- CompilerStack c;
- c.addSource("a", "contract C { modifier M(uint i) { _; } function F() M(1) {} }");
- c.setEVMVersion(dev::test::Options::get().evmVersion());
- c.parseAndAnalyze();
- map<string, unsigned> sourceIndices;
- sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- Json::Value modifier = astJson["children"][0]["children"][0];
- BOOST_CHECK_EQUAL(modifier["name"], "ModifierDefinition");
- BOOST_CHECK_EQUAL(modifier["attributes"]["name"], "M");
- BOOST_CHECK_EQUAL(modifier["src"], "13:25:1");
-}
-
-BOOST_AUTO_TEST_CASE(modifier_invocation)
-{
- CompilerStack c;
- c.addSource("a", "contract C { modifier M(uint i) { _; } function F() M(1) {} }");
- c.setEVMVersion(dev::test::Options::get().evmVersion());
- c.parseAndAnalyze();
- map<string, unsigned> sourceIndices;
- sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- Json::Value modifier = astJson["children"][0]["children"][1]["children"][2];
- BOOST_CHECK_EQUAL(modifier["name"], "ModifierInvocation");
- BOOST_CHECK_EQUAL(modifier["src"], "52:4:1");
- BOOST_CHECK_EQUAL(modifier["children"][0]["attributes"]["type"], "modifier (uint256)");
- BOOST_CHECK_EQUAL(modifier["children"][0]["attributes"]["value"], "M");
- BOOST_CHECK_EQUAL(modifier["children"][1]["attributes"]["value"], "1");
-}
-
-BOOST_AUTO_TEST_CASE(event_definition)
-{
- CompilerStack c;
- c.addSource("a", "contract C { event E(); }");
- c.setEVMVersion(dev::test::Options::get().evmVersion());
- c.parseAndAnalyze();
- map<string, unsigned> sourceIndices;
- sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- Json::Value event = astJson["children"][0]["children"][0];
- BOOST_CHECK_EQUAL(event["name"], "EventDefinition");
- BOOST_CHECK_EQUAL(event["attributes"]["name"], "E");
- BOOST_CHECK_EQUAL(event["src"], "13:10:1");
-}
-
-BOOST_AUTO_TEST_CASE(array_type_name)
-{
- CompilerStack c;
- c.addSource("a", "contract C { uint[] i; }");
- c.setEVMVersion(dev::test::Options::get().evmVersion());
- c.parseAndAnalyze();
- map<string, unsigned> sourceIndices;
- sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- Json::Value array = astJson["children"][0]["children"][0]["children"][0];
- BOOST_CHECK_EQUAL(array["name"], "ArrayTypeName");
- BOOST_CHECK_EQUAL(array["src"], "13:6:1");
-}
-
-BOOST_AUTO_TEST_CASE(placeholder_statement)
-{
- CompilerStack c;
- c.addSource("a", "contract C { modifier M { _; } }");
- c.setEVMVersion(dev::test::Options::get().evmVersion());
- c.parseAndAnalyze();
- map<string, unsigned> sourceIndices;
- sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- Json::Value placeholder = astJson["children"][0]["children"][0]["children"][1]["children"][0];
- BOOST_CHECK_EQUAL(placeholder["name"], "PlaceholderStatement");
- BOOST_CHECK_EQUAL(placeholder["src"], "26:1:1");
-}
-
-BOOST_AUTO_TEST_CASE(non_utf8)
-{
- CompilerStack c;
- c.addSource("a", "contract C { function f() { var x = hex\"ff\"; } }");
- c.setEVMVersion(dev::test::Options::get().evmVersion());
- c.parseAndAnalyze();
- map<string, unsigned> sourceIndices;
- sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- Json::Value literal = astJson["children"][0]["children"][0]["children"][2]["children"][0]["children"][1];
- BOOST_CHECK_EQUAL(literal["name"], "Literal");
- BOOST_CHECK_EQUAL(literal["attributes"]["hexvalue"], "ff");
- BOOST_CHECK_EQUAL(literal["attributes"]["token"], "string");
- BOOST_CHECK_EQUAL(literal["attributes"]["value"], Json::nullValue);
- BOOST_CHECK(literal["attributes"]["type"].asString().find("invalid") != string::npos);
-}
-
-BOOST_AUTO_TEST_CASE(function_type)
-{
- CompilerStack c;
- c.addSource("a",
- "contract C { function f(function() external payable returns (uint) x) "
- "returns (function() external constant returns (uint)) {} }"
- );
- c.setEVMVersion(dev::test::Options::get().evmVersion());
- c.parseAndAnalyze();
- map<string, unsigned> sourceIndices;
- sourceIndices["a"] = 1;
- Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- Json::Value fun = astJson["children"][0]["children"][0];
- BOOST_CHECK_EQUAL(fun["name"], "FunctionDefinition");
- Json::Value argument = fun["children"][0]["children"][0];
- BOOST_CHECK_EQUAL(argument["name"], "VariableDeclaration");
- BOOST_CHECK_EQUAL(argument["attributes"]["name"], "x");
- BOOST_CHECK_EQUAL(argument["attributes"]["type"], "function () payable external returns (uint256)");
- Json::Value funType = argument["children"][0];
- BOOST_CHECK_EQUAL(funType["attributes"]["constant"], false);
- BOOST_CHECK_EQUAL(funType["attributes"]["payable"], true);
- BOOST_CHECK_EQUAL(funType["attributes"]["visibility"], "external");
- Json::Value retval = fun["children"][1]["children"][0];
- BOOST_CHECK_EQUAL(retval["name"], "VariableDeclaration");
- BOOST_CHECK_EQUAL(retval["attributes"]["name"], "");
- BOOST_CHECK_EQUAL(retval["attributes"]["type"], "function () view external returns (uint256)");
- funType = retval["children"][0];
- BOOST_CHECK_EQUAL(funType["attributes"]["constant"], true);
- BOOST_CHECK_EQUAL(funType["attributes"]["payable"], false);
- BOOST_CHECK_EQUAL(funType["attributes"]["visibility"], "external");
+ Json::Value astJson = ASTJsonConverter(false, sourceIndices).toJson(c.ast("a"));
+ Json::Value varDecl = astJson["nodes"][0]["nodes"][1]["body"]["statements"][0]["initialValue"];
+ BOOST_CHECK_EQUAL(varDecl["typeDescriptions"]["typeIdentifier"], "t_array$_t_uint256_$dyn_storage");
+ BOOST_CHECK_EQUAL(varDecl["typeDescriptions"]["typeString"], "uint256[] storage ref");
}
BOOST_AUTO_TEST_CASE(documentation)
@@ -266,30 +121,17 @@ BOOST_AUTO_TEST_CASE(documentation)
sourceIndices["a"] = 0;
sourceIndices["b"] = 1;
sourceIndices["c"] = 2;
- Json::Value astJsonA = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
- Json::Value documentationA = astJsonA["children"][0]["attributes"]["documentation"];
- BOOST_CHECK_EQUAL(documentationA, "This contract is empty");
- Json::Value astJsonB = ASTJsonConverter(true, sourceIndices).toJson(c.ast("b"));
- Json::Value documentationB = astJsonB["children"][0]["attributes"]["documentation"];
- BOOST_CHECK_EQUAL(documentationB, "This contract is empty and has a line-breaking comment.");
- Json::Value astJsonC = ASTJsonConverter(true, sourceIndices).toJson(c.ast("c"));
- Json::Value documentationC0 = astJsonC["children"][0]["children"][0]["attributes"]["documentation"];
- Json::Value documentationC1 = astJsonC["children"][0]["children"][1]["attributes"]["documentation"];
- Json::Value documentationC2 = astJsonC["children"][0]["children"][2]["attributes"]["documentation"];
- BOOST_CHECK_EQUAL(documentationC0, "Some comment on Evt.");
- BOOST_CHECK_EQUAL(documentationC1, "Some comment on mod.");
- BOOST_CHECK_EQUAL(documentationC2, "Some comment on fn.");
//same tests for non-legacy mode
- astJsonA = ASTJsonConverter(false, sourceIndices).toJson(c.ast("a"));
- documentationA = astJsonA["nodes"][0]["documentation"];
+ Json::Value astJsonA = ASTJsonConverter(false, sourceIndices).toJson(c.ast("a"));
+ Json::Value documentationA = astJsonA["nodes"][0]["documentation"];
BOOST_CHECK_EQUAL(documentationA, "This contract is empty");
- astJsonB = ASTJsonConverter(false, sourceIndices).toJson(c.ast("b"));
- documentationB = astJsonB["nodes"][0]["documentation"];
+ Json::Value astJsonB = ASTJsonConverter(false, sourceIndices).toJson(c.ast("b"));
+ Json::Value documentationB = astJsonB["nodes"][0]["documentation"];
BOOST_CHECK_EQUAL(documentationB, "This contract is empty and has a line-breaking comment.");
- astJsonC = ASTJsonConverter(false, sourceIndices).toJson(c.ast("c"));
- documentationC0 = astJsonC["nodes"][0]["nodes"][0]["documentation"];
- documentationC1 = astJsonC["nodes"][0]["nodes"][1]["documentation"];
- documentationC2 = astJsonC["nodes"][0]["nodes"][2]["documentation"];
+ Json::Value astJsonC = ASTJsonConverter(false, sourceIndices).toJson(c.ast("c"));
+ Json::Value documentationC0 = astJsonC["nodes"][0]["nodes"][0]["documentation"];
+ Json::Value documentationC1 = astJsonC["nodes"][0]["nodes"][1]["documentation"];
+ Json::Value documentationC2 = astJsonC["nodes"][0]["nodes"][2]["documentation"];
BOOST_CHECK_EQUAL(documentationC0, "Some comment on Evt.");
BOOST_CHECK_EQUAL(documentationC1, "Some comment on mod.");
BOOST_CHECK_EQUAL(documentationC2, "Some comment on fn.");
diff --git a/test/libsolidity/ASTLegacyJSON.cpp b/test/libsolidity/ASTLegacyJSON.cpp
new file mode 100644
index 00000000..13148682
--- /dev/null
+++ b/test/libsolidity/ASTLegacyJSON.cpp
@@ -0,0 +1,324 @@
+/*
+ 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/>.
+*/
+/**
+ * @author Christian <c@ethdev.com>
+ * @date 2016
+ * Tests for the json ast output.
+ */
+
+#include <test/Options.h>
+
+#include <libsolidity/interface/Exceptions.h>
+#include <libsolidity/interface/CompilerStack.h>
+#include <libsolidity/ast/ASTJsonConverter.h>
+
+#include <boost/test/unit_test.hpp>
+
+#include <string>
+
+using namespace std;
+
+namespace dev
+{
+namespace solidity
+{
+namespace test
+{
+
+BOOST_AUTO_TEST_SUITE(SolidityASTLegacyJSON)
+
+BOOST_AUTO_TEST_CASE(smoke_test)
+{
+ CompilerStack c;
+ c.addSource("a", "contract C {}");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ BOOST_CHECK_EQUAL(astJson["name"], "SourceUnit");
+}
+
+BOOST_AUTO_TEST_CASE(source_location)
+{
+ CompilerStack c;
+ c.addSource("a", "contract C { function f() { var x = 2; x++; } }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ BOOST_CHECK_EQUAL(astJson["name"], "SourceUnit");
+ BOOST_CHECK_EQUAL(astJson["children"][0]["name"], "ContractDefinition");
+ BOOST_CHECK_EQUAL(astJson["children"][0]["children"][0]["name"], "FunctionDefinition");
+ BOOST_CHECK_EQUAL(astJson["children"][0]["children"][0]["src"], "13:32:1");
+
+}
+
+BOOST_AUTO_TEST_CASE(inheritance_specifier)
+{
+ CompilerStack c;
+ c.addSource("a", "contract C1 {} contract C2 is C1 {}");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ BOOST_CHECK_EQUAL(astJson["children"][1]["attributes"]["name"], "C2");
+ BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["name"], "InheritanceSpecifier");
+ BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["src"], "30:2:1");
+ BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["children"][0]["name"], "UserDefinedTypeName");
+ BOOST_CHECK_EQUAL(astJson["children"][1]["children"][0]["children"][0]["attributes"]["name"], "C1");
+}
+
+BOOST_AUTO_TEST_CASE(using_for_directive)
+{
+ CompilerStack c;
+ c.addSource("a", "library L {} contract C { using L for uint; }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value usingFor = astJson["children"][1]["children"][0];
+ BOOST_CHECK_EQUAL(usingFor["name"], "UsingForDirective");
+ BOOST_CHECK_EQUAL(usingFor["src"], "26:17:1");
+ BOOST_CHECK_EQUAL(usingFor["children"][0]["name"], "UserDefinedTypeName");
+ BOOST_CHECK_EQUAL(usingFor["children"][0]["attributes"]["name"], "L");
+ BOOST_CHECK_EQUAL(usingFor["children"][1]["name"], "ElementaryTypeName");
+ BOOST_CHECK_EQUAL(usingFor["children"][1]["attributes"]["name"], "uint");
+}
+
+BOOST_AUTO_TEST_CASE(enum_value)
+{
+ CompilerStack c;
+ c.addSource("a", "contract C { enum E { A, B } }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value enumDefinition = astJson["children"][0]["children"][0];
+ BOOST_CHECK_EQUAL(enumDefinition["children"][0]["name"], "EnumValue");
+ BOOST_CHECK_EQUAL(enumDefinition["children"][0]["attributes"]["name"], "A");
+ BOOST_CHECK_EQUAL(enumDefinition["children"][0]["src"], "22:1:1");
+ BOOST_CHECK_EQUAL(enumDefinition["children"][1]["name"], "EnumValue");
+ BOOST_CHECK_EQUAL(enumDefinition["children"][1]["attributes"]["name"], "B");
+ BOOST_CHECK_EQUAL(enumDefinition["children"][1]["src"], "25:1:1");
+}
+
+BOOST_AUTO_TEST_CASE(modifier_definition)
+{
+ CompilerStack c;
+ c.addSource("a", "contract C { modifier M(uint i) { _; } function F() M(1) {} }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value modifier = astJson["children"][0]["children"][0];
+ BOOST_CHECK_EQUAL(modifier["name"], "ModifierDefinition");
+ BOOST_CHECK_EQUAL(modifier["attributes"]["name"], "M");
+ BOOST_CHECK_EQUAL(modifier["src"], "13:25:1");
+}
+
+BOOST_AUTO_TEST_CASE(modifier_invocation)
+{
+ CompilerStack c;
+ c.addSource("a", "contract C { modifier M(uint i) { _; } function F() M(1) {} }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value modifier = astJson["children"][0]["children"][1]["children"][2];
+ BOOST_CHECK_EQUAL(modifier["name"], "ModifierInvocation");
+ BOOST_CHECK_EQUAL(modifier["src"], "52:4:1");
+ BOOST_CHECK_EQUAL(modifier["children"][0]["attributes"]["type"], "modifier (uint256)");
+ BOOST_CHECK_EQUAL(modifier["children"][0]["attributes"]["value"], "M");
+ BOOST_CHECK_EQUAL(modifier["children"][1]["attributes"]["value"], "1");
+}
+
+BOOST_AUTO_TEST_CASE(event_definition)
+{
+ CompilerStack c;
+ c.addSource("a", "contract C { event E(); }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value event = astJson["children"][0]["children"][0];
+ BOOST_CHECK_EQUAL(event["name"], "EventDefinition");
+ BOOST_CHECK_EQUAL(event["attributes"]["name"], "E");
+ BOOST_CHECK_EQUAL(event["src"], "13:10:1");
+}
+
+BOOST_AUTO_TEST_CASE(array_type_name)
+{
+ CompilerStack c;
+ c.addSource("a", "contract C { uint[] i; }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value arrayDecl = astJson["children"][0]["children"][0]["attributes"];
+ BOOST_CHECK_EQUAL(arrayDecl["storageLocation"], "default");
+ BOOST_CHECK_EQUAL(arrayDecl["type"], "uint256[]");
+ Json::Value array = astJson["children"][0]["children"][0]["children"][0];
+ BOOST_CHECK_EQUAL(array["name"], "ArrayTypeName");
+ BOOST_CHECK_EQUAL(array["src"], "13:6:1");
+}
+
+BOOST_AUTO_TEST_CASE(short_type_name)
+{
+ CompilerStack c;
+ c.addSource("a", "contract c { function f() { uint[] memory x; } }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value arrayDecl = astJson["children"][0]["children"][0]["children"][2]["children"][0]["children"][0];
+ BOOST_CHECK_EQUAL(arrayDecl["attributes"]["storageLocation"], "memory");
+ BOOST_CHECK_EQUAL(arrayDecl["attributes"]["type"], "uint256[]");
+}
+
+BOOST_AUTO_TEST_CASE(short_type_name_ref)
+{
+ CompilerStack c;
+ c.addSource("a", "contract c { function f() { uint[][] memory rows; } }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value arrayDecl = astJson["children"][0]["children"][0]["children"][2]["children"][0]["children"][0];
+ BOOST_CHECK_EQUAL(arrayDecl["attributes"]["storageLocation"], "memory");
+ BOOST_CHECK_EQUAL(arrayDecl["attributes"]["type"], "uint256[][]");
+}
+
+BOOST_AUTO_TEST_CASE(placeholder_statement)
+{
+ CompilerStack c;
+ c.addSource("a", "contract C { modifier M { _; } }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value placeholder = astJson["children"][0]["children"][0]["children"][1]["children"][0];
+ BOOST_CHECK_EQUAL(placeholder["name"], "PlaceholderStatement");
+ BOOST_CHECK_EQUAL(placeholder["src"], "26:1:1");
+}
+
+BOOST_AUTO_TEST_CASE(non_utf8)
+{
+ CompilerStack c;
+ c.addSource("a", "contract C { function f() { var x = hex\"ff\"; } }");
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value varDecl = astJson["children"][0]["children"][0]["children"][2]["children"][0]["children"][0];
+ BOOST_CHECK_EQUAL(varDecl["attributes"]["type"], "string");
+ BOOST_CHECK_EQUAL(varDecl["attributes"]["typeName"], Json::nullValue);
+ Json::Value literal = astJson["children"][0]["children"][0]["children"][2]["children"][0]["children"][1];
+ BOOST_CHECK_EQUAL(literal["name"], "Literal");
+ BOOST_CHECK_EQUAL(literal["attributes"]["hexvalue"], "ff");
+ BOOST_CHECK_EQUAL(literal["attributes"]["token"], "string");
+ BOOST_CHECK_EQUAL(literal["attributes"]["value"], Json::nullValue);
+ BOOST_CHECK(literal["attributes"]["type"].asString().find("invalid") != string::npos);
+}
+
+BOOST_AUTO_TEST_CASE(function_type)
+{
+ CompilerStack c;
+ c.addSource("a",
+ "contract C { function f(function() external payable returns (uint) x) "
+ "returns (function() external constant returns (uint)) {} }"
+ );
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 1;
+ Json::Value astJson = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value fun = astJson["children"][0]["children"][0];
+ BOOST_CHECK_EQUAL(fun["name"], "FunctionDefinition");
+ Json::Value argument = fun["children"][0]["children"][0];
+ BOOST_CHECK_EQUAL(argument["name"], "VariableDeclaration");
+ BOOST_CHECK_EQUAL(argument["attributes"]["name"], "x");
+ BOOST_CHECK_EQUAL(argument["attributes"]["type"], "function () payable external returns (uint256)");
+ Json::Value funType = argument["children"][0];
+ BOOST_CHECK_EQUAL(funType["attributes"]["constant"], false);
+ BOOST_CHECK_EQUAL(funType["attributes"]["payable"], true);
+ BOOST_CHECK_EQUAL(funType["attributes"]["visibility"], "external");
+ Json::Value retval = fun["children"][1]["children"][0];
+ BOOST_CHECK_EQUAL(retval["name"], "VariableDeclaration");
+ BOOST_CHECK_EQUAL(retval["attributes"]["name"], "");
+ BOOST_CHECK_EQUAL(retval["attributes"]["type"], "function () view external returns (uint256)");
+ funType = retval["children"][0];
+ BOOST_CHECK_EQUAL(funType["attributes"]["constant"], true);
+ BOOST_CHECK_EQUAL(funType["attributes"]["payable"], false);
+ BOOST_CHECK_EQUAL(funType["attributes"]["visibility"], "external");
+}
+
+BOOST_AUTO_TEST_CASE(documentation)
+{
+ CompilerStack c;
+ c.addSource("a", "/**This contract is empty*/ contract C {}");
+ c.addSource("b",
+ "/**This contract is empty"
+ " and has a line-breaking comment.*/"
+ "contract C {}"
+ );
+ c.addSource("c",
+ "contract C {"
+ " /** Some comment on Evt.*/ event Evt();"
+ " /** Some comment on mod.*/ modifier mod() { _; }"
+ " /** Some comment on fn.*/ function fn() public {}"
+ "}"
+ );
+ c.setEVMVersion(dev::test::Options::get().evmVersion());
+ c.parseAndAnalyze();
+ map<string, unsigned> sourceIndices;
+ sourceIndices["a"] = 0;
+ sourceIndices["b"] = 1;
+ sourceIndices["c"] = 2;
+ Json::Value astJsonA = ASTJsonConverter(true, sourceIndices).toJson(c.ast("a"));
+ Json::Value documentationA = astJsonA["children"][0]["attributes"]["documentation"];
+ BOOST_CHECK_EQUAL(documentationA, "This contract is empty");
+ Json::Value astJsonB = ASTJsonConverter(true, sourceIndices).toJson(c.ast("b"));
+ Json::Value documentationB = astJsonB["children"][0]["attributes"]["documentation"];
+ BOOST_CHECK_EQUAL(documentationB, "This contract is empty and has a line-breaking comment.");
+ Json::Value astJsonC = ASTJsonConverter(true, sourceIndices).toJson(c.ast("c"));
+ Json::Value documentationC0 = astJsonC["children"][0]["children"][0]["attributes"]["documentation"];
+ Json::Value documentationC1 = astJsonC["children"][0]["children"][1]["attributes"]["documentation"];
+ Json::Value documentationC2 = astJsonC["children"][0]["children"][2]["attributes"]["documentation"];
+ BOOST_CHECK_EQUAL(documentationC0, "Some comment on Evt.");
+ BOOST_CHECK_EQUAL(documentationC1, "Some comment on mod.");
+ BOOST_CHECK_EQUAL(documentationC2, "Some comment on fn.");
+}
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}
+}
+} // end namespaces
diff --git a/test/libsolidity/AnalysisFramework.cpp b/test/libsolidity/AnalysisFramework.cpp
index 7c335a48..72b86767 100644
--- a/test/libsolidity/AnalysisFramework.cpp
+++ b/test/libsolidity/AnalysisFramework.cpp
@@ -20,7 +20,7 @@
#include <test/libsolidity/AnalysisFramework.h>
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libsolidity/interface/CompilerStack.h>
#include <libsolidity/interface/SourceReferenceFormatter.h>
@@ -56,12 +56,23 @@ AnalysisFramework::parseAnalyseAndReturnError(
m_compiler.analyze();
+ ErrorList errors = filterErrors(m_compiler.errors(), _reportWarnings);
+ if (errors.size() > 1 && !_allowMultipleErrors)
+ BOOST_FAIL("Multiple errors found: " + formatErrors());
+
+ return make_pair(&m_compiler.ast(""), std::move(errors));
+}
+
+ErrorList AnalysisFramework::filterErrors(ErrorList const& _errorList, bool _includeWarnings) const
+{
ErrorList errors;
- for (auto const& currentError: m_compiler.errors())
+ for (auto const& currentError: _errorList)
{
solAssert(currentError->comment(), "");
if (currentError->type() == Error::Type::Warning)
{
+ if (!_includeWarnings)
+ continue;
bool ignoreWarning = false;
for (auto const& filter: m_warningsToFilter)
if (currentError->comment()->find(filter) == 0)
@@ -73,17 +84,10 @@ AnalysisFramework::parseAnalyseAndReturnError(
continue;
}
- if (_reportWarnings || (currentError->type() != Error::Type::Warning))
- {
- if (!_allowMultipleErrors && !errors.empty())
- {
- BOOST_FAIL("Multiple errors found: " + formatErrors());
- }
- errors.emplace_back(std::move(currentError));
- }
+ errors.emplace_back(currentError);
}
- return make_pair(&m_compiler.ast(""), errors);
+ return errors;
}
SourceUnit const* AnalysisFramework::parseAndAnalyse(string const& _source)
@@ -110,7 +114,7 @@ ErrorList AnalysisFramework::expectError(std::string const& _source, bool _warni
return sourceAndErrors.second;
}
-string AnalysisFramework::formatErrors()
+string AnalysisFramework::formatErrors() const
{
string message;
for (auto const& error: m_compiler.errors())
@@ -118,7 +122,7 @@ string AnalysisFramework::formatErrors()
return message;
}
-string AnalysisFramework::formatError(Error const& _error)
+string AnalysisFramework::formatError(Error const& _error) const
{
return SourceReferenceFormatter::formatExceptionInformation(
_error,
diff --git a/test/libsolidity/AnalysisFramework.h b/test/libsolidity/AnalysisFramework.h
index 6ecf4a5a..05490a42 100644
--- a/test/libsolidity/AnalysisFramework.h
+++ b/test/libsolidity/AnalysisFramework.h
@@ -57,8 +57,8 @@ protected:
bool success(std::string const& _source);
ErrorList expectError(std::string const& _source, bool _warning = false, bool _allowMultiple = false);
- std::string formatErrors();
- std::string formatError(Error const& _error);
+ std::string formatErrors() const;
+ std::string formatError(Error const& _error) const;
static ContractDefinition const* retrieveContractByName(SourceUnit const& _source, std::string const& _name);
static FunctionTypePointer retrieveFunctionBySignature(
@@ -66,6 +66,9 @@ protected:
std::string const& _signature
);
+ // filter out the warnings in m_warningsToFilter or all warnings if _includeWarnings is false
+ ErrorList filterErrors(ErrorList const& _errorList, bool _includeWarnings) const;
+
std::vector<std::string> m_warningsToFilter = {"This is a pre-release compiler version"};
dev::solidity::CompilerStack m_compiler;
};
diff --git a/test/libsolidity/Assembly.cpp b/test/libsolidity/Assembly.cpp
index aff610a4..77ca363a 100644
--- a/test/libsolidity/Assembly.cpp
+++ b/test/libsolidity/Assembly.cpp
@@ -20,7 +20,7 @@
* Unit tests for Assembly Items from evmasm/Assembly.h
*/
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libevmasm/SourceLocation.h>
#include <libevmasm/Assembly.h>
@@ -157,14 +157,23 @@ BOOST_AUTO_TEST_CASE(location_test)
}
}
)";
- shared_ptr<string const> n = make_shared<string>("");
AssemblyItems items = compileContract(sourceCode);
vector<SourceLocation> locations =
- vector<SourceLocation>(24, SourceLocation(2, 75, n)) +
- vector<SourceLocation>(32, SourceLocation(20, 72, n)) +
- vector<SourceLocation>{SourceLocation(42, 51, n), SourceLocation(65, 67, n)} +
- vector<SourceLocation>(2, SourceLocation(58, 67, n)) +
- vector<SourceLocation>(2, SourceLocation(20, 72, n));
+ vector<SourceLocation>(24, SourceLocation(2, 75, make_shared<string>(""))) +
+ vector<SourceLocation>(2, SourceLocation(20, 72, make_shared<string>(""))) +
+ vector<SourceLocation>(1, SourceLocation(8, 17, make_shared<string>("--CODEGEN--"))) +
+ vector<SourceLocation>(3, SourceLocation(5, 7, make_shared<string>("--CODEGEN--"))) +
+ vector<SourceLocation>(1, SourceLocation(30, 31, make_shared<string>("--CODEGEN--"))) +
+ vector<SourceLocation>(1, SourceLocation(27, 28, make_shared<string>("--CODEGEN--"))) +
+ vector<SourceLocation>(1, SourceLocation(20, 32, make_shared<string>("--CODEGEN--"))) +
+ vector<SourceLocation>(1, SourceLocation(5, 7, make_shared<string>("--CODEGEN--"))) +
+ vector<SourceLocation>(24, SourceLocation(20, 72, make_shared<string>(""))) +
+ vector<SourceLocation>(1, SourceLocation(42, 51, make_shared<string>(""))) +
+ vector<SourceLocation>(1, SourceLocation(65, 67, make_shared<string>(""))) +
+ vector<SourceLocation>(2, SourceLocation(58, 67, make_shared<string>(""))) +
+ vector<SourceLocation>(2, SourceLocation(20, 72, make_shared<string>("")));
+
+
checkAssemblyLocations(items, locations);
}
diff --git a/test/libsolidity/FormattedScope.h b/test/libsolidity/FormattedScope.h
new file mode 100644
index 00000000..923404f0
--- /dev/null
+++ b/test/libsolidity/FormattedScope.h
@@ -0,0 +1,68 @@
+/*
+ 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/>.
+*/
+
+#pragma once
+
+#include <boost/noncopyable.hpp>
+
+#include <ostream>
+#include <vector>
+
+namespace dev
+{
+namespace solidity
+{
+namespace test
+{
+
+namespace formatting
+{
+
+static constexpr char const* RESET = "\033[0m";
+static constexpr char const* RED = "\033[1;31m";
+static constexpr char const* GREEN = "\033[1;32m";
+static constexpr char const* YELLOW = "\033[1;33m";
+static constexpr char const* CYAN = "\033[1;36m";
+static constexpr char const* BOLD = "\033[1m";
+static constexpr char const* RED_BACKGROUND = "\033[48;5;160m";
+static constexpr char const* ORANGE_BACKGROUND = "\033[48;5;166m";
+static constexpr char const* INVERSE = "\033[7m";
+
+}
+
+class FormattedScope: boost::noncopyable
+{
+public:
+ /// @arg _formatting List of formatting strings (e.g. colors) defined in the formatting namespace.
+ FormattedScope(std::ostream& _stream, bool const _enabled, std::vector<char const*> const& _formatting):
+ m_stream(_stream), m_enabled(_enabled)
+ {
+ if (m_enabled)
+ for (auto const& format: _formatting)
+ m_stream << format;
+ }
+ ~FormattedScope() { if (m_enabled) m_stream << formatting::RESET; }
+ template<typename T>
+ std::ostream& operator<<(T&& _t) { return m_stream << std::forward<T>(_t); }
+private:
+ std::ostream& m_stream;
+ bool m_enabled;
+};
+
+}
+}
+}
diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp
index fd2017f9..0d66456c 100644
--- a/test/libsolidity/GasMeter.cpp
+++ b/test/libsolidity/GasMeter.cpp
@@ -294,6 +294,19 @@ BOOST_AUTO_TEST_CASE(extcodesize_gas)
testRunTimeGas("f()", vector<bytes>{encodeArgs()});
}
+BOOST_AUTO_TEST_CASE(regular_functions_exclude_fallback)
+{
+ // A bug in the estimator caused the costs for a specific function
+ // to always include the costs for the fallback.
+ char const* sourceCode = R"(
+ contract A {
+ uint public x;
+ function() { x = 2; }
+ }
+ )";
+ testCreationTimeGas(sourceCode);
+ testRunTimeGas("x()", vector<bytes>{encodeArgs()});
+}
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/Imports.cpp b/test/libsolidity/Imports.cpp
index bc81b3b1..1b5dd4a5 100644
--- a/test/libsolidity/Imports.cpp
+++ b/test/libsolidity/Imports.cpp
@@ -21,7 +21,7 @@
*/
#include <test/libsolidity/ErrorCheck.h>
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/interface/CompilerStack.h>
diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp
index a4dcc4d5..0ced1792 100644
--- a/test/libsolidity/InlineAssembly.cpp
+++ b/test/libsolidity/InlineAssembly.cpp
@@ -20,7 +20,7 @@
* Unit tests for inline assembly.
*/
-#include "../TestHelper.h"
+#include <test/Options.h>
#include <libsolidity/interface/AssemblyStack.h>
#include <libsolidity/parsing/Scanner.h>
@@ -783,6 +783,8 @@ BOOST_AUTO_TEST_CASE(shift)
BOOST_AUTO_TEST_CASE(shift_constantinople_warning)
{
+ if (dev::test::Options::get().evmVersion().hasBitwiseShifting())
+ return;
CHECK_PARSE_WARNING("{ pop(shl(10, 32)) }", Warning, "The \"shl\" instruction is only available for Constantinople-compatible VMs.");
CHECK_PARSE_WARNING("{ pop(shr(10, 32)) }", Warning, "The \"shr\" instruction is only available for Constantinople-compatible VMs.");
CHECK_PARSE_WARNING("{ pop(sar(10, 32)) }", Warning, "The \"sar\" instruction is only available for Constantinople-compatible VMs.");
diff --git a/test/libsolidity/JSONCompiler.cpp b/test/libsolidity/JSONCompiler.cpp
index 285c5604..2b3df3a7 100644
--- a/test/libsolidity/JSONCompiler.cpp
+++ b/test/libsolidity/JSONCompiler.cpp
@@ -25,8 +25,8 @@
#include <libsolidity/interface/Version.h>
#include <libsolc/libsolc.h>
-#include "../Metadata.h"
-#include "../TestHelper.h"
+#include <test/Metadata.h>
+#include <test/Options.h>
using namespace std;
@@ -111,18 +111,18 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
BOOST_CHECK(contract["bytecode"].isString());
BOOST_CHECK_EQUAL(
dev::test::bytecodeSansMetadata(contract["bytecode"].asString()),
- "60606040523415600e57600080fd5b603580601b6000396000f3006060604052600080fd00"
+ "6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00"
);
BOOST_CHECK(contract["runtimeBytecode"].isString());
BOOST_CHECK_EQUAL(
dev::test::bytecodeSansMetadata(contract["runtimeBytecode"].asString()),
- "6060604052600080fd00"
+ "6080604052600080fd00"
);
BOOST_CHECK(contract["functionHashes"].isObject());
BOOST_CHECK(contract["gasEstimates"].isObject());
BOOST_CHECK_EQUAL(
dev::jsonCompactPrint(contract["gasEstimates"]),
- "{\"creation\":[61,10600],\"external\":{},\"internal\":{}}"
+ "{\"creation\":[66,10600],\"external\":{},\"internal\":{}}"
);
BOOST_CHECK(contract["metadata"].isString());
BOOST_CHECK(dev::test::isValidMetadata(contract["metadata"].asString()));
@@ -153,18 +153,18 @@ BOOST_AUTO_TEST_CASE(single_compilation)
BOOST_CHECK(contract["bytecode"].isString());
BOOST_CHECK_EQUAL(
dev::test::bytecodeSansMetadata(contract["bytecode"].asString()),
- "60606040523415600e57600080fd5b603580601b6000396000f3006060604052600080fd00"
+ "6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00"
);
BOOST_CHECK(contract["runtimeBytecode"].isString());
BOOST_CHECK_EQUAL(
dev::test::bytecodeSansMetadata(contract["runtimeBytecode"].asString()),
- "6060604052600080fd00"
+ "6080604052600080fd00"
);
BOOST_CHECK(contract["functionHashes"].isObject());
BOOST_CHECK(contract["gasEstimates"].isObject());
BOOST_CHECK_EQUAL(
dev::jsonCompactPrint(contract["gasEstimates"]),
- "{\"creation\":[61,10600],\"external\":{},\"internal\":{}}"
+ "{\"creation\":[66,10600],\"external\":{},\"internal\":{}}"
);
BOOST_CHECK(contract["metadata"].isString());
BOOST_CHECK(dev::test::isValidMetadata(contract["metadata"].asString()));
diff --git a/test/libsolidity/Metadata.cpp b/test/libsolidity/Metadata.cpp
index f1edeeb7..808bd1e1 100644
--- a/test/libsolidity/Metadata.cpp
+++ b/test/libsolidity/Metadata.cpp
@@ -19,8 +19,8 @@
* Unit tests for the metadata output.
*/
-#include "../Metadata.h"
-#include "../TestHelper.h"
+#include <test/Metadata.h>
+#include <test/Options.h>
#include <libsolidity/interface/CompilerStack.h>
#include <libdevcore/SwarmHash.h>
#include <libdevcore/JSON.h>
diff --git a/test/libsolidity/SMTChecker.cpp b/test/libsolidity/SMTChecker.cpp
index 12b5f439..beb933a4 100644
--- a/test/libsolidity/SMTChecker.cpp
+++ b/test/libsolidity/SMTChecker.cpp
@@ -329,6 +329,144 @@ BOOST_AUTO_TEST_CASE(ways_to_merge_variables)
CHECK_WARNING(text, "Assertion violation happens here");
}
+BOOST_AUTO_TEST_CASE(bool_simple)
+{
+ string text = R"(
+ contract C {
+ function f(bool x) public pure {
+ assert(x);
+ }
+ }
+ )";
+ CHECK_WARNING(text, "Assertion violation happens here");
+ text = R"(
+ contract C {
+ function f(bool x, bool y) public pure {
+ assert(x == y);
+ }
+ }
+ )";
+ CHECK_WARNING(text, "Assertion violation happens here");
+ text = R"(
+ contract C {
+ function f(bool x, bool y) public pure {
+ bool z = x || y;
+ assert(!(x && y) || z);
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+ text = R"(
+ contract C {
+ function f(bool x) public pure {
+ if(x) {
+ assert(x);
+ } else {
+ assert(!x);
+ }
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+ text = R"(
+ contract C {
+ function f(bool x) public pure {
+ bool y = x;
+ assert(x == y);
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+ text = R"(
+ contract C {
+ function f(bool x) public pure {
+ require(x);
+ bool y;
+ y = false;
+ assert(x || y);
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+ text = R"(
+ contract C {
+ function f(bool x) public pure {
+ bool y;
+ assert(x <= y);
+ }
+ }
+ )";
+ CHECK_WARNING(text, "Assertion violation happens here");
+ text = R"(
+ contract C {
+ function f(bool x) public pure {
+ bool y;
+ assert(x >= y);
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+ text = R"(
+ contract C {
+ function f(bool x) public pure {
+ require(x);
+ bool y;
+ assert(x > y);
+ assert(y < x);
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(bool_int_mixed)
+{
+ string text = R"(
+ contract C {
+ function f(bool x) public pure {
+ uint a;
+ if(x)
+ a = 1;
+ assert(!x || a > 0);
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+ text = R"(
+ contract C {
+ function f(bool x, uint a) public pure {
+ require(!x || a > 0);
+ uint b = a;
+ assert(!x || b > 0);
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+ text = R"(
+ contract C {
+ function f(bool x, bool y) public pure {
+ uint a;
+ if (x) {
+ if (y) {
+ a = 0;
+ } else {
+ a = 1;
+ }
+ } else {
+ if (y) {
+ a = 1;
+ } else {
+ a = 0;
+ }
+ }
+ bool xor_x_y = (x && !y) || (!x && y);
+ assert(!xor_x_y || a > 0);
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
BOOST_AUTO_TEST_CASE(while_loop_simple)
{
// Check that variables are cleared
diff --git a/test/libsolidity/SemVerMatcher.cpp b/test/libsolidity/SemVerMatcher.cpp
index 08ef5277..07f8fba6 100644
--- a/test/libsolidity/SemVerMatcher.cpp
+++ b/test/libsolidity/SemVerMatcher.cpp
@@ -25,7 +25,7 @@
#include <tuple>
#include <libsolidity/parsing/Scanner.h>
#include <libsolidity/analysis/SemVerHandler.h>
-#include "../TestHelper.h"
+#include <test/Options.h>
using namespace std;
diff --git a/test/libsolidity/SolidityABIJSON.cpp b/test/libsolidity/SolidityABIJSON.cpp
index 0d471b32..107abc26 100644
--- a/test/libsolidity/SolidityABIJSON.cpp
+++ b/test/libsolidity/SolidityABIJSON.cpp
@@ -20,7 +20,7 @@
* Unit tests for the solidity compiler JSON Interface output.
*/
-#include "../TestHelper.h"
+#include <test/Options.h>
#include <libsolidity/interface/CompilerStack.h>
#include <libdevcore/Exceptions.h>
diff --git a/test/libsolidity/SolidityCompiler.cpp b/test/libsolidity/SolidityCompiler.cpp
new file mode 100644
index 00000000..90540f3e
--- /dev/null
+++ b/test/libsolidity/SolidityCompiler.cpp
@@ -0,0 +1,60 @@
+/*
+ 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/>.
+ */
+/**
+ * Unit tests for the compiler itself.
+ */
+
+#include <test/libsolidity/AnalysisFramework.h>
+
+#include <test/Options.h>
+
+using namespace std;
+
+namespace dev
+{
+namespace solidity
+{
+namespace test
+{
+
+BOOST_FIXTURE_TEST_SUITE(Compiler, AnalysisFramework)
+
+BOOST_AUTO_TEST_CASE(does_not_include_creation_time_only_internal_functions)
+{
+ char const* sourceCode = R"(
+ contract C {
+ uint x;
+ function C() { f(); }
+ function f() internal { for (uint i = 0; i < 10; ++i) x += 3 + i; }
+ }
+ )";
+ BOOST_REQUIRE(success(sourceCode));
+ m_compiler.setOptimiserSettings(dev::test::Options::get().optimize);
+ BOOST_REQUIRE_MESSAGE(m_compiler.compile(), "Compiling contract failed");
+ bytes const& creationBytecode = m_compiler.object("C").bytecode;
+ bytes const& runtimeBytecode = m_compiler.runtimeObject("C").bytecode;
+ BOOST_CHECK(creationBytecode.size() >= 130);
+ BOOST_CHECK(creationBytecode.size() <= 160);
+ BOOST_CHECK(runtimeBytecode.size() >= 50);
+ BOOST_CHECK(runtimeBytecode.size() <= 70);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+}
+}
+}
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 33cd1419..789b89d1 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -23,7 +23,7 @@
#include <test/libsolidity/SolidityExecutionFramework.h>
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/interface/EVMVersion.h>
@@ -102,6 +102,29 @@ BOOST_AUTO_TEST_CASE(exp_operator_const_signed)
ABI_CHECK(callContractFunction("f()", bytes()), toBigEndian(u256(-8)));
}
+BOOST_AUTO_TEST_CASE(exp_zero)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f(uint a) returns(uint d) { return a ** 0; }
+ }
+ )";
+ compileAndRun(sourceCode);
+ testContractAgainstCppOnRange("f(uint256)", [](u256 const&) -> u256 { return u256(1); }, 0, 16);
+}
+
+BOOST_AUTO_TEST_CASE(exp_zero_literal)
+{
+ char const* sourceCode = R"(
+ contract test {
+ function f() returns(uint d) { return 0 ** 0; }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("f()", bytes()), toBigEndian(u256(1)));
+}
+
+
BOOST_AUTO_TEST_CASE(conditional_expression_true_literal)
{
char const* sourceCode = R"(
@@ -1788,6 +1811,35 @@ BOOST_AUTO_TEST_CASE(transfer_ether)
ABI_CHECK(callContractFunction("b(address,uint256)", oogRecipient, 10), encodeArgs());
}
+BOOST_AUTO_TEST_CASE(uncalled_blockhash)
+{
+ char const* code = R"(
+ contract C {
+ function f() public view returns (bytes32)
+ {
+ var x = block.blockhash;
+ return x(block.number - 1);
+ }
+ }
+ )";
+ compileAndRun(code, 0, "C");
+ bytes result = callContractFunction("f()");
+ BOOST_REQUIRE_EQUAL(result.size(), 32);
+ BOOST_CHECK(result[0] != 0 || result[1] != 0 || result[2] != 0);
+}
+
+BOOST_AUTO_TEST_CASE(blockhash_shadow_resolution)
+{
+ char const* code = R"(
+ contract C {
+ function blockhash(uint256 blockNumber) public returns(bytes32) { bytes32 x; return x; }
+ function f() public returns(bytes32) { return blockhash(3); }
+ }
+ )";
+ compileAndRun(code, 0, "C");
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(0));
+}
+
BOOST_AUTO_TEST_CASE(log0)
{
char const* sourceCode = R"(
@@ -2048,6 +2100,31 @@ BOOST_AUTO_TEST_CASE(packed_keccak256)
testContractAgainstCpp("a(bytes32)", f, u256(-1));
}
+BOOST_AUTO_TEST_CASE(packed_keccak256_complex_types)
+{
+ char const* sourceCode = R"(
+ contract test {
+ uint120[3] x;
+ function f() view returns (bytes32 hash1, bytes32 hash2, bytes32 hash3) {
+ uint120[] memory y = new uint120[](3);
+ x[0] = y[0] = uint120(-2);
+ x[1] = y[1] = uint120(-3);
+ x[2] = y[2] = uint120(-4);
+ hash1 = keccak256(x);
+ hash2 = keccak256(y);
+ hash3 = keccak256(this.f);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ // Strangely, arrays are encoded with intra-element padding.
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(
+ dev::keccak256(encodeArgs(u256("0xfffffffffffffffffffffffffffffe"), u256("0xfffffffffffffffffffffffffffffd"), u256("0xfffffffffffffffffffffffffffffc"))),
+ dev::keccak256(encodeArgs(u256("0xfffffffffffffffffffffffffffffe"), u256("0xfffffffffffffffffffffffffffffd"), u256("0xfffffffffffffffffffffffffffffc"))),
+ dev::keccak256(fromHex(m_contractAddress.hex() + "26121ff0"))
+ ));
+}
+
BOOST_AUTO_TEST_CASE(packed_sha256)
{
char const* sourceCode = R"(
@@ -2879,6 +2956,58 @@ BOOST_AUTO_TEST_CASE(function_modifier_multiple_times_local_vars)
ABI_CHECK(callContractFunction("a()"), encodeArgs(0));
}
+BOOST_AUTO_TEST_CASE(function_modifier_library)
+{
+ char const* sourceCode = R"(
+ library L {
+ struct S { uint v; }
+ modifier mod(S storage s) { s.v++; _; }
+ function libFun(S storage s) mod(s) internal { s.v += 0x100; }
+ }
+
+ contract Test {
+ using L for *;
+ L.S s;
+
+ function f() public returns (uint) {
+ s.libFun();
+ L.libFun(s);
+ return s.v;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(0x202));
+}
+
+BOOST_AUTO_TEST_CASE(function_modifier_library_inheritance)
+{
+ // Tests that virtual lookup for modifiers in libraries does not consider
+ // the current inheritance hierarchy.
+
+ char const* sourceCode = R"(
+ library L {
+ struct S { uint v; }
+ modifier mod(S storage s) { s.v++; _; }
+ function libFun(S storage s) mod(s) internal { s.v += 0x100; }
+ }
+
+ contract Test {
+ using L for *;
+ L.S s;
+ modifier mod(L.S storage) { revert(); _; }
+
+ function f() public returns (uint) {
+ s.libFun();
+ L.libFun(s);
+ return s.v;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(0x202));
+}
+
BOOST_AUTO_TEST_CASE(crazy_elementary_typenames_on_stack)
{
char const* sourceCode = R"(
@@ -3451,6 +3580,45 @@ BOOST_AUTO_TEST_CASE(empty_name_return_parameter)
ABI_CHECK(callContractFunction("f(uint256)", 9), encodeArgs(9));
}
+BOOST_AUTO_TEST_CASE(sha256_empty)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (bytes32) {
+ return sha256();
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("f()"), fromHex("0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));
+}
+
+BOOST_AUTO_TEST_CASE(ripemd160_empty)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (bytes20) {
+ return ripemd160();
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("f()"), fromHex("0x9c1185a5c5e9fc54612808977ee8f548b2258d31000000000000000000000000"));
+}
+
+BOOST_AUTO_TEST_CASE(keccak256_empty)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (bytes32) {
+ return keccak256();
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("f()"), fromHex("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
+}
+
BOOST_AUTO_TEST_CASE(keccak256_multiple_arguments)
{
char const* sourceCode = R"(
@@ -4778,6 +4946,48 @@ BOOST_AUTO_TEST_CASE(array_push)
ABI_CHECK(callContractFunction("test()"), encodeArgs(5, 4, 3, 3));
}
+BOOST_AUTO_TEST_CASE(array_push_struct)
+{
+ char const* sourceCode = R"(
+ contract c {
+ struct S { uint16 a; uint16 b; uint16[3] c; uint16[] d; }
+ S[] data;
+ function test() returns (uint16, uint16, uint16, uint16) {
+ S memory s;
+ s.a = 2;
+ s.b = 3;
+ s.c[2] = 4;
+ s.d = new uint16[](4);
+ s.d[2] = 5;
+ data.push(s);
+ return (data[0].a, data[0].b, data[0].c[2], data[0].d[2]);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("test()"), encodeArgs(2, 3, 4, 5));
+}
+
+BOOST_AUTO_TEST_CASE(array_push_packed_array)
+{
+ char const* sourceCode = R"(
+ contract c {
+ uint80[] x;
+ function test() returns (uint80, uint80, uint80, uint80) {
+ x.push(1);
+ x.push(2);
+ x.push(3);
+ x.push(4);
+ x.push(5);
+ x.length = 4;
+ return (x[0], x[1], x[2], x[3]);
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("test()"), encodeArgs(1, 2, 3, 4));
+}
+
BOOST_AUTO_TEST_CASE(byte_array_push)
{
char const* sourceCode = R"(
@@ -4798,6 +5008,29 @@ BOOST_AUTO_TEST_CASE(byte_array_push)
ABI_CHECK(callContractFunction("test()"), encodeArgs(false));
}
+BOOST_AUTO_TEST_CASE(byte_array_push_transition)
+{
+ // Tests transition between short and long encoding
+ char const* sourceCode = R"(
+ contract c {
+ bytes data;
+ function test() returns (uint) {
+ for (uint i = 1; i < 40; i++)
+ {
+ data.push(byte(i));
+ if (data.length != i) return 0x1000 + i;
+ if (data[data.length - 1] != byte(i)) return i;
+ }
+ for (i = 1; i < 40; i++)
+ if (data[i - 1] != byte(i)) return 0x1000000 + i;
+ return 0;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ ABI_CHECK(callContractFunction("test()"), encodeArgs(0));
+}
+
BOOST_AUTO_TEST_CASE(external_array_args)
{
char const* sourceCode = R"(
@@ -5020,7 +5253,7 @@ BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base)
}
uint public m_i;
}
- contract Derived is Base(2) {
+ contract Derived is Base {
function Derived(uint i) Base(i)
{}
}
@@ -5040,10 +5273,10 @@ BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base_base)
}
uint public m_i;
}
- contract Base1 is Base(3) {
+ contract Base1 is Base {
function Base1(uint k) Base(k*k) {}
}
- contract Derived is Base(3), Base1(2) {
+ contract Derived is Base, Base1 {
function Derived(uint i) Base(i) Base1(i)
{}
}
@@ -5064,7 +5297,7 @@ BOOST_AUTO_TEST_CASE(pass_dynamic_arguments_to_the_base_base_with_gap)
uint public m_i;
}
contract Base1 is Base(3) {}
- contract Derived is Base(2), Base1 {
+ contract Derived is Base, Base1 {
function Derived(uint i) Base(i) {}
}
contract Final is Derived(4) {
@@ -6955,6 +7188,21 @@ BOOST_AUTO_TEST_CASE(library_call)
ABI_CHECK(callContractFunction("f(uint256)", u256(33)), encodeArgs(u256(33) * 9));
}
+BOOST_AUTO_TEST_CASE(library_function_external)
+{
+ char const* sourceCode = R"(
+ library Lib { function m(bytes b) external pure returns (byte) { return b[2]; } }
+ contract Test {
+ function f(bytes b) public pure returns (byte) {
+ return Lib.m(b);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "Lib");
+ compileAndRun(sourceCode, 0, "Test", bytes(), map<string, Address>{{"Lib", m_contractAddress}});
+ ABI_CHECK(callContractFunction("f(bytes)", u256(0x20), u256(5), "abcde"), encodeArgs("c"));
+}
+
BOOST_AUTO_TEST_CASE(library_stray_values)
{
char const* sourceCode = R"(
@@ -7566,7 +7814,6 @@ BOOST_AUTO_TEST_CASE(create_memory_array_allocation_size)
ABI_CHECK(callContractFunction("f()"), encodeArgs(0x40, 0x40, 0x20 + 256));
}
-
BOOST_AUTO_TEST_CASE(memory_arrays_of_various_sizes)
{
// Computes binomial coefficients the chinese way
@@ -7589,6 +7836,41 @@ BOOST_AUTO_TEST_CASE(memory_arrays_of_various_sizes)
ABI_CHECK(callContractFunction("f(uint256,uint256)", encodeArgs(u256(9), u256(5))), encodeArgs(u256(70)));
}
+BOOST_AUTO_TEST_CASE(create_multiple_dynamic_arrays)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() returns (uint) {
+ uint[][] memory x = new uint[][](42);
+ assert(x[0].length == 0);
+ x[0] = new uint[](1);
+ x[0][0] = 1;
+ assert(x[4].length == 0);
+ x[4] = new uint[](1);
+ x[4][0] = 2;
+ assert(x[10].length == 0);
+ x[10] = new uint[](1);
+ x[10][0] = 44;
+ uint[][] memory y = new uint[][](24);
+ assert(y[0].length == 0);
+ y[0] = new uint[](1);
+ y[0][0] = 1;
+ assert(y[4].length == 0);
+ y[4] = new uint[](1);
+ y[4][0] = 2;
+ assert(y[10].length == 0);
+ y[10] = new uint[](1);
+ y[10][0] = 88;
+ if ((x[0][0] == y[0][0]) && (x[4][0] == y[4][0]) && (x[10][0] == 44) && (y[10][0] == 88))
+ return 7;
+ return 0;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7)));
+}
+
BOOST_AUTO_TEST_CASE(memory_overwrite)
{
char const* sourceCode = R"(
@@ -7627,12 +7909,12 @@ BOOST_AUTO_TEST_CASE(addmod_mulmod_zero)
{
char const* sourceCode = R"(
contract C {
- function f() pure returns (uint) {
- addmod(1, 2, 0);
+ function f(uint d) pure returns (uint) {
+ addmod(1, 2, d);
return 2;
}
- function g() pure returns (uint) {
- mulmod(1, 2, 0);
+ function g(uint d) pure returns (uint) {
+ mulmod(1, 2, d);
return 2;
}
function h() pure returns (uint) {
@@ -7645,8 +7927,8 @@ BOOST_AUTO_TEST_CASE(addmod_mulmod_zero)
}
)";
compileAndRun(sourceCode);
- ABI_CHECK(callContractFunction("f()"), encodeArgs());
- ABI_CHECK(callContractFunction("g()"), encodeArgs());
+ ABI_CHECK(callContractFunction("f(uint)", 0), encodeArgs());
+ ABI_CHECK(callContractFunction("g(uint)", 0), encodeArgs());
ABI_CHECK(callContractFunction("h()"), encodeArgs(2));
}
@@ -8548,6 +8830,24 @@ BOOST_AUTO_TEST_CASE(cleanup_bytes_types)
ABI_CHECK(callContractFunction("f(bytes2,uint16)", string("abc"), u256(0x040102)), encodeArgs(0));
}
+BOOST_AUTO_TEST_CASE(cleanup_bytes_types_shortening)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f() pure returns (bytes32 r) {
+ bytes4 x = 0xffffffff;
+ bytes2 y = bytes2(x);
+ assembly { r := y }
+ // At this point, r and y both store four bytes, but
+ // y is properly cleaned before the equality check
+ require(y == bytes2(0xffff));
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f()"), encodeArgs("\xff\xff\xff\xff"));
+}
+
BOOST_AUTO_TEST_CASE(skip_dynamic_types)
{
// The EVM cannot provide access to dynamically-sized return values, so we have to skip them.
@@ -8635,6 +8935,32 @@ BOOST_AUTO_TEST_CASE(create_dynamic_array_with_zero_length)
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7)));
}
+BOOST_AUTO_TEST_CASE(correctly_initialize_memory_array_in_constructor)
+{
+ // Memory arrays are initialized using codecopy past the size of the code.
+ // This test checks that it also works in the constructor context.
+ char const* sourceCode = R"(
+ contract C {
+ bool public success;
+ function C() public {
+ // Make memory dirty.
+ assembly {
+ for { let i := 0 } lt(i, 64) { i := add(i, 1) } {
+ mstore(msize, not(0))
+ }
+ }
+ uint16[3] memory c;
+ require(c[0] == 0 && c[1] == 0 && c[2] == 0);
+ uint16[] memory x = new uint16[](3);
+ require(x[0] == 0 && x[1] == 0 && x[2] == 0);
+ success = true;
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("success()"), encodeArgs(u256(1)));
+}
+
BOOST_AUTO_TEST_CASE(return_does_not_skip_modifier)
{
char const* sourceCode = R"(
@@ -8998,7 +9324,7 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function_in_detail)
int mutex;
function t() returns (uint) {
if (mutex > 0)
- return 7;
+ { assembly { mstore(0, 7) return(0, 0x20) } }
mutex = 1;
// Avoid re-executing this function if we jump somewhere.
x();
@@ -9011,6 +9337,27 @@ BOOST_AUTO_TEST_CASE(calling_uninitialized_function_in_detail)
ABI_CHECK(callContractFunction("t()"), encodeArgs());
}
+BOOST_AUTO_TEST_CASE(calling_uninitialized_function_through_array)
+{
+ char const* sourceCode = R"(
+ contract C {
+ int mutex;
+ function t() returns (uint) {
+ if (mutex > 0)
+ { assembly { mstore(0, 7) return(0, 0x20) } }
+ mutex = 1;
+ // Avoid re-executing this function if we jump somewhere.
+ function() internal returns (uint)[200] x;
+ x[0]();
+ return 2;
+ }
+ }
+ )";
+
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("t()"), encodeArgs());
+}
+
BOOST_AUTO_TEST_CASE(pass_function_types_internally)
{
char const* sourceCode = R"(
@@ -10152,6 +10499,214 @@ BOOST_AUTO_TEST_CASE(revert)
ABI_CHECK(callContractFunction("a()"), encodeArgs(u256(42)));
}
+BOOST_AUTO_TEST_CASE(revert_with_cause)
+{
+ char const* sourceCode = R"(
+ contract D {
+ function f() public {
+ revert("test123");
+ }
+ function g() public {
+ revert("test1234567890123456789012345678901234567890");
+ }
+ }
+ contract C {
+ D d = new D();
+ function forward(address target, bytes data) internal returns (bool success, bytes retval) {
+ uint retsize;
+ assembly {
+ success := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0)
+ retsize := returndatasize()
+ }
+ retval = new bytes(retsize);
+ assembly {
+ returndatacopy(add(retval, 0x20), 0, returndatasize())
+ }
+ }
+ function f() public returns (bool, bytes) {
+ return forward(address(d), msg.data);
+ }
+ function g() public returns (bool, bytes) {
+ return forward(address(d), msg.data);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ bool const haveReturndata = dev::test::Options::get().evmVersion().supportsReturndata();
+ bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
+ ABI_CHECK(callContractFunction("f()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, "test123") + bytes(28, 0) : bytes());
+ ABI_CHECK(callContractFunction("g()"), haveReturndata ? encodeArgs(0, 0x40, 0x84) + errorSignature + encodeArgs(0x20, 44, "test1234567890123456789012345678901234567890") + bytes(28, 0): bytes());
+}
+
+BOOST_AUTO_TEST_CASE(require_with_message)
+{
+ char const* sourceCode = R"(
+ contract D {
+ bool flag = false;
+ string storageError = "abc";
+ function f(uint x) public {
+ require(x > 7, "failed");
+ }
+ function g() public {
+ // As a side-effect of internalFun, the flag will be set to true
+ // (even if the condition is true),
+ // but it will only throw in the next evaluation.
+ bool flagCopy = flag;
+ require(flagCopy == false, internalFun());
+ }
+ function internalFun() returns (string) {
+ flag = true;
+ return "only on second run";
+ }
+ function h() public {
+ require(false, storageError);
+ }
+ }
+ contract C {
+ D d = new D();
+ function forward(address target, bytes data) internal returns (bool success, bytes retval) {
+ uint retsize;
+ assembly {
+ success := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0)
+ retsize := returndatasize()
+ }
+ retval = new bytes(retsize);
+ assembly {
+ returndatacopy(add(retval, 0x20), 0, returndatasize())
+ }
+ }
+ function f(uint x) public returns (bool, bytes) {
+ return forward(address(d), msg.data);
+ }
+ function g() public returns (bool, bytes) {
+ return forward(address(d), msg.data);
+ }
+ function h() public returns (bool, bytes) {
+ return forward(address(d), msg.data);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ bool const haveReturndata = dev::test::Options::get().evmVersion().supportsReturndata();
+ bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
+ ABI_CHECK(callContractFunction("f(uint256)", 8), haveReturndata ? encodeArgs(1, 0x40, 0) : bytes());
+ ABI_CHECK(callContractFunction("f(uint256)", 5), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 6, "failed") + bytes(28, 0) : bytes());
+ ABI_CHECK(callContractFunction("g()"), haveReturndata ? encodeArgs(1, 0x40, 0) : bytes());
+ ABI_CHECK(callContractFunction("g()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 18, "only on second run") + bytes(28, 0) : bytes());
+ ABI_CHECK(callContractFunction("h()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 3, "abc") + bytes(28, 0): bytes());
+}
+
+BOOST_AUTO_TEST_CASE(bubble_up_error_messages)
+{
+ char const* sourceCode = R"(
+ contract D {
+ function f() public {
+ revert("message");
+ }
+ function g() public {
+ this.f();
+ }
+ }
+ contract C {
+ D d = new D();
+ function forward(address target, bytes data) internal returns (bool success, bytes retval) {
+ uint retsize;
+ assembly {
+ success := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0)
+ retsize := returndatasize()
+ }
+ retval = new bytes(retsize);
+ assembly {
+ returndatacopy(add(retval, 0x20), 0, returndatasize())
+ }
+ }
+ function f() public returns (bool, bytes) {
+ return forward(address(d), msg.data);
+ }
+ function g() public returns (bool, bytes) {
+ return forward(address(d), msg.data);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ bool const haveReturndata = dev::test::Options::get().evmVersion().supportsReturndata();
+ bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
+ ABI_CHECK(callContractFunction("f()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, "message") + bytes(28, 0) : bytes());
+ ABI_CHECK(callContractFunction("g()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, "message") + bytes(28, 0) : bytes());
+}
+
+BOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_transfer)
+{
+ char const* sourceCode = R"(
+ contract D {
+ function() public payable {
+ revert("message");
+ }
+ function f() public {
+ this.transfer(0);
+ }
+ }
+ contract C {
+ D d = new D();
+ function forward(address target, bytes data) internal returns (bool success, bytes retval) {
+ uint retsize;
+ assembly {
+ success := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0)
+ retsize := returndatasize()
+ }
+ retval = new bytes(retsize);
+ assembly {
+ returndatacopy(add(retval, 0x20), 0, returndatasize())
+ }
+ }
+ function f() public returns (bool, bytes) {
+ return forward(address(d), msg.data);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ bool const haveReturndata = dev::test::Options::get().evmVersion().supportsReturndata();
+ bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
+ ABI_CHECK(callContractFunction("f()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, "message") + bytes(28, 0) : bytes());
+}
+
+BOOST_AUTO_TEST_CASE(bubble_up_error_messages_through_create)
+{
+ char const* sourceCode = R"(
+ contract E {
+ function E() {
+ revert("message");
+ }
+ }
+ contract D {
+ function f() public {
+ var x = new E();
+ }
+ }
+ contract C {
+ D d = new D();
+ function forward(address target, bytes data) internal returns (bool success, bytes retval) {
+ uint retsize;
+ assembly {
+ success := call(not(0), target, 0, add(data, 0x20), mload(data), 0, 0)
+ retsize := returndatasize()
+ }
+ retval = new bytes(retsize);
+ assembly {
+ returndatacopy(add(retval, 0x20), 0, returndatasize())
+ }
+ }
+ function f() public returns (bool, bytes) {
+ return forward(address(d), msg.data);
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ bool const haveReturndata = dev::test::Options::get().evmVersion().supportsReturndata();
+ bytes const errorSignature = bytes{0x08, 0xc3, 0x79, 0xa0};
+ ABI_CHECK(callContractFunction("f()"), haveReturndata ? encodeArgs(0, 0x40, 0x64) + errorSignature + encodeArgs(0x20, 7, "message") + bytes(28, 0) : bytes());
+}
+
BOOST_AUTO_TEST_CASE(negative_stack_height)
{
// This code was causing negative stack height during code generation
@@ -10785,6 +11340,329 @@ BOOST_AUTO_TEST_CASE(snark)
BOOST_CHECK(callContractFunction("verifyTx()") == encodeArgs(true));
}
+BOOST_AUTO_TEST_CASE(abi_encode)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f0() returns (bytes) {
+ return abi.encode();
+ }
+ function f1() returns (bytes) {
+ return abi.encode(1, 2);
+ }
+ function f2() returns (bytes) {
+ string memory x = "abc";
+ return abi.encode(1, x, 2);
+ }
+ function f3() returns (bytes r) {
+ // test that memory is properly allocated
+ string memory x = "abc";
+ r = abi.encode(1, x, 2);
+ bytes memory y = "def";
+ require(y[0] == "d");
+ y[0] = "e";
+ require(y[0] == "e");
+ }
+ function f4() returns (bytes) {
+ bytes4 x = "abcd";
+ return abi.encode(bytes2(x));
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f0()"), encodeArgs(0x20, 0));
+ ABI_CHECK(callContractFunction("f1()"), encodeArgs(0x20, 0x40, 1, 2));
+ ABI_CHECK(callContractFunction("f2()"), encodeArgs(0x20, 0xa0, 1, 0x60, 2, 3, "abc"));
+ ABI_CHECK(callContractFunction("f3()"), encodeArgs(0x20, 0xa0, 1, 0x60, 2, 3, "abc"));
+ ABI_CHECK(callContractFunction("f4()"), encodeArgs(0x20, 0x20, "ab"));
+}
+
+BOOST_AUTO_TEST_CASE(abi_encode_v2)
+{
+ char const* sourceCode = R"(
+ pragma experimental ABIEncoderV2;
+ contract C {
+ struct S { uint a; uint[] b; }
+ function f0() public pure returns (bytes) {
+ return abi.encode();
+ }
+ function f1() public pure returns (bytes) {
+ return abi.encode(1, 2);
+ }
+ function f2() public pure returns (bytes) {
+ string memory x = "abc";
+ return abi.encode(1, x, 2);
+ }
+ function f3() public pure returns (bytes r) {
+ // test that memory is properly allocated
+ string memory x = "abc";
+ r = abi.encode(1, x, 2);
+ bytes memory y = "def";
+ require(y[0] == "d");
+ y[0] = "e";
+ require(y[0] == "e");
+ }
+ S s;
+ function f4() public view returns (bytes r) {
+ string memory x = "abc";
+ s.a = 7;
+ s.b.push(2);
+ s.b.push(3);
+ r = abi.encode(1, x, s, 2);
+ bytes memory y = "def";
+ require(y[0] == "d");
+ y[0] = "e";
+ require(y[0] == "e");
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f0()"), encodeArgs(0x20, 0));
+ ABI_CHECK(callContractFunction("f1()"), encodeArgs(0x20, 0x40, 1, 2));
+ ABI_CHECK(callContractFunction("f2()"), encodeArgs(0x20, 0xa0, 1, 0x60, 2, 3, "abc"));
+ ABI_CHECK(callContractFunction("f3()"), encodeArgs(0x20, 0xa0, 1, 0x60, 2, 3, "abc"));
+ ABI_CHECK(callContractFunction("f4()"), encodeArgs(0x20, 0x160, 1, 0x80, 0xc0, 2, 3, "abc", 7, 0x40, 2, 2, 3));
+}
+
+
+BOOST_AUTO_TEST_CASE(abi_encodePacked)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f0() public pure returns (bytes) {
+ return abi.encodePacked();
+ }
+ function f1() public pure returns (bytes) {
+ return abi.encodePacked(uint8(1), uint8(2));
+ }
+ function f2() public pure returns (bytes) {
+ string memory x = "abc";
+ return abi.encodePacked(uint8(1), x, uint8(2));
+ }
+ function f3() public pure returns (bytes r) {
+ // test that memory is properly allocated
+ string memory x = "abc";
+ r = abi.encodePacked(uint8(1), x, uint8(2));
+ bytes memory y = "def";
+ require(y[0] == "d");
+ y[0] = "e";
+ require(y[0] == "e");
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f0()"), encodeArgs(0x20, 0));
+ ABI_CHECK(callContractFunction("f1()"), encodeArgs(0x20, 2, "\x01\x02"));
+ ABI_CHECK(callContractFunction("f2()"), encodeArgs(0x20, 5, "\x01" "abc" "\x02"));
+ ABI_CHECK(callContractFunction("f3()"), encodeArgs(0x20, 5, "\x01" "abc" "\x02"));
+}
+
+BOOST_AUTO_TEST_CASE(abi_encode_with_selector)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function f0() public pure returns (bytes) {
+ return abi.encodeWithSelector(0x12345678);
+ }
+ function f1() public pure returns (bytes) {
+ return abi.encodeWithSelector(0x12345678, "abc");
+ }
+ function f2() public pure returns (bytes) {
+ bytes4 x = 0x12345678;
+ return abi.encodeWithSelector(x, "abc");
+ }
+ function f3() public pure returns (bytes) {
+ bytes4 x = 0x12345678;
+ return abi.encodeWithSelector(x, uint(-1));
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f0()"), encodeArgs(0x20, 4, "\x12\x34\x56\x78"));
+ bytes expectation;
+ expectation = encodeArgs(0x20, 4 + 0x60) + bytes{0x12, 0x34, 0x56, 0x78} + encodeArgs(0x20, 3, "abc") + bytes(0x20 - 4);
+ ABI_CHECK(callContractFunction("f1()"), expectation);
+ expectation = encodeArgs(0x20, 4 + 0x60) + bytes{0x12, 0x34, 0x56, 0x78} + encodeArgs(0x20, 3, "abc") + bytes(0x20 - 4);
+ ABI_CHECK(callContractFunction("f2()"), expectation);
+ expectation = encodeArgs(0x20, 4 + 0x20) + bytes{0x12, 0x34, 0x56, 0x78} + encodeArgs(u256(-1)) + bytes(0x20 - 4);
+ ABI_CHECK(callContractFunction("f3()"), expectation);
+}
+
+BOOST_AUTO_TEST_CASE(abi_encode_with_selectorv2)
+{
+ char const* sourceCode = R"(
+ pragma experimental ABIEncoderV2;
+ contract C {
+ function f0() public pure returns (bytes) {
+ return abi.encodeWithSelector(0x12345678);
+ }
+ function f1() public pure returns (bytes) {
+ return abi.encodeWithSelector(0x12345678, "abc");
+ }
+ function f2() public pure returns (bytes) {
+ bytes4 x = 0x12345678;
+ return abi.encodeWithSelector(x, "abc");
+ }
+ function f3() public pure returns (bytes) {
+ bytes4 x = 0x12345678;
+ return abi.encodeWithSelector(x, uint(-1));
+ }
+ struct S { uint a; string b; uint16 c; }
+ function f4() public pure returns (bytes) {
+ bytes4 x = 0x12345678;
+ S memory s;
+ s.a = 0x1234567;
+ s.b = "Lorem ipsum dolor sit ethereum........";
+ s.c = 0x1234;
+ return abi.encodeWithSelector(x, uint(-1), s, uint(3));
+ }
+ }
+ )";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f0()"), encodeArgs(0x20, 4, "\x12\x34\x56\x78"));
+ bytes expectation;
+ expectation = encodeArgs(0x20, 4 + 0x60) + bytes{0x12, 0x34, 0x56, 0x78} + encodeArgs(0x20, 3, "abc") + bytes(0x20 - 4);
+ ABI_CHECK(callContractFunction("f1()"), expectation);
+ expectation = encodeArgs(0x20, 4 + 0x60) + bytes{0x12, 0x34, 0x56, 0x78} + encodeArgs(0x20, 3, "abc") + bytes(0x20 - 4);
+ ABI_CHECK(callContractFunction("f2()"), expectation);
+ expectation = encodeArgs(0x20, 4 + 0x20) + bytes{0x12, 0x34, 0x56, 0x78} + encodeArgs(u256(-1)) + bytes(0x20 - 4);
+ ABI_CHECK(callContractFunction("f3()"), expectation);
+ expectation =
+ encodeArgs(0x20, 4 + 0x120) +
+ bytes{0x12, 0x34, 0x56, 0x78} +
+ encodeArgs(u256(-1), 0x60, u256(3), 0x1234567, 0x60, 0x1234, 38, "Lorem ipsum dolor sit ethereum........") +
+ bytes(0x20 - 4);
+ ABI_CHECK(callContractFunction("f4()"), expectation);
+}
+
+BOOST_AUTO_TEST_CASE(abi_encode_with_signature)
+{
+ char const* sourceCode = R"T(
+ contract C {
+ function f0() public pure returns (bytes) {
+ return abi.encodeWithSignature("f(uint256)");
+ }
+ function f1() public pure returns (bytes) {
+ string memory x = "f(uint256)";
+ return abi.encodeWithSignature(x, "abc");
+ }
+ string xstor;
+ function f1s() public returns (bytes) {
+ xstor = "f(uint256)";
+ return abi.encodeWithSignature(xstor, "abc");
+ }
+ function f2() public pure returns (bytes r, uint[] ar) {
+ string memory x = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
+ uint[] memory y = new uint[](4);
+ y[0] = uint(-1);
+ y[1] = uint(-2);
+ y[2] = uint(-3);
+ y[3] = uint(-4);
+ r = abi.encodeWithSignature(x, y);
+ // The hash uses temporary memory. This allocation re-uses the memory
+ // and should initialize it properly.
+ ar = new uint[](2);
+ }
+ }
+ )T";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f0()"), encodeArgs(0x20, 4, "\xb3\xde\x64\x8b"));
+ bytes expectation;
+ expectation = encodeArgs(0x20, 4 + 0x60) + bytes{0xb3, 0xde, 0x64, 0x8b} + encodeArgs(0x20, 3, "abc") + bytes(0x20 - 4);
+ ABI_CHECK(callContractFunction("f1()"), expectation);
+ ABI_CHECK(callContractFunction("f1s()"), expectation);
+ expectation =
+ encodeArgs(0x40, 0x140, 4 + 0xc0) +
+ (bytes{0xe9, 0xc9, 0x21, 0xcd} + encodeArgs(0x20, 4, u256(-1), u256(-2), u256(-3), u256(-4)) + bytes(0x20 - 4)) +
+ encodeArgs(2, 0, 0);
+ ABI_CHECK(callContractFunction("f2()"), expectation);
+}
+
+BOOST_AUTO_TEST_CASE(abi_encode_with_signaturev2)
+{
+ char const* sourceCode = R"T(
+ pragma experimental ABIEncoderV2;
+ contract C {
+ function f0() public pure returns (bytes) {
+ return abi.encodeWithSignature("f(uint256)");
+ }
+ function f1() public pure returns (bytes) {
+ string memory x = "f(uint256)";
+ return abi.encodeWithSignature(x, "abc");
+ }
+ string xstor;
+ function f1s() public returns (bytes) {
+ xstor = "f(uint256)";
+ return abi.encodeWithSignature(xstor, "abc");
+ }
+ function f2() public pure returns (bytes r, uint[] ar) {
+ string memory x = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
+ uint[] memory y = new uint[](4);
+ y[0] = uint(-1);
+ y[1] = uint(-2);
+ y[2] = uint(-3);
+ y[3] = uint(-4);
+ r = abi.encodeWithSignature(x, y);
+ // The hash uses temporary memory. This allocation re-uses the memory
+ // and should initialize it properly.
+ ar = new uint[](2);
+ }
+ struct S { uint a; string b; uint16 c; }
+ function f4() public pure returns (bytes) {
+ bytes4 x = 0x12345678;
+ S memory s;
+ s.a = 0x1234567;
+ s.b = "Lorem ipsum dolor sit ethereum........";
+ s.c = 0x1234;
+ return abi.encodeWithSignature(s.b, uint(-1), s, uint(3));
+ }
+ }
+ )T";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f0()"), encodeArgs(0x20, 4, "\xb3\xde\x64\x8b"));
+ bytes expectation;
+ expectation = encodeArgs(0x20, 4 + 0x60) + bytes{0xb3, 0xde, 0x64, 0x8b} + encodeArgs(0x20, 3, "abc") + bytes(0x20 - 4);
+ ABI_CHECK(callContractFunction("f1()"), expectation);
+ ABI_CHECK(callContractFunction("f1s()"), expectation);
+ expectation =
+ encodeArgs(0x40, 0x140, 4 + 0xc0) +
+ (bytes{0xe9, 0xc9, 0x21, 0xcd} + encodeArgs(0x20, 4, u256(-1), u256(-2), u256(-3), u256(-4)) + bytes(0x20 - 4)) +
+ encodeArgs(2, 0, 0);
+ ABI_CHECK(callContractFunction("f2()"), expectation);
+ expectation =
+ encodeArgs(0x20, 4 + 0x120) +
+ bytes{0x7c, 0x79, 0x30, 0x02} +
+ encodeArgs(u256(-1), 0x60, u256(3), 0x1234567, 0x60, 0x1234, 38, "Lorem ipsum dolor sit ethereum........") +
+ bytes(0x20 - 4);
+ ABI_CHECK(callContractFunction("f4()"), expectation);
+}
+
+BOOST_AUTO_TEST_CASE(abi_encode_call)
+{
+ char const* sourceCode = R"T(
+ contract C {
+ bool x;
+ function c(uint a, uint[] b) public {
+ require(a == 5);
+ require(b.length == 2);
+ require(b[0] == 6);
+ require(b[1] == 7);
+ x = true;
+ }
+ function f() public returns (bool) {
+ uint a = 5;
+ uint[] memory b = new uint[](2);
+ b[0] = 6;
+ b[1] = 7;
+ require(this.call(abi.encodeWithSignature("c(uint256,uint256[])", a, b)));
+ return x;
+ }
+ }
+ )T";
+ compileAndRun(sourceCode, 0, "C");
+ ABI_CHECK(callContractFunction("f()"), encodeArgs(true));
+}
+
BOOST_AUTO_TEST_CASE(staticcall_for_view_and_pure)
{
char const* sourceCode = R"(
@@ -10830,6 +11708,179 @@ BOOST_AUTO_TEST_CASE(staticcall_for_view_and_pure)
}
}
+BOOST_AUTO_TEST_CASE(swap_peephole_optimisation)
+{
+ char const* sourceCode = R"(
+ contract C {
+ function lt(uint a, uint b) returns (bool c) {
+ assembly {
+ a
+ b
+ swap1
+ lt
+ =: c
+ }
+ }
+ function add(uint a, uint b) returns (uint c) {
+ assembly {
+ a
+ b
+ swap1
+ add
+ =: c
+ }
+ }
+ function div(uint a, uint b) returns (uint c) {
+ assembly {
+ a
+ b
+ swap1
+ div
+ =: c
+ }
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("lt(uint256,uint256)", u256(1), u256(2)) == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("lt(uint256,uint256)", u256(2), u256(1)) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("add(uint256,uint256)", u256(1), u256(2)) == encodeArgs(u256(3)));
+ BOOST_CHECK(callContractFunction("add(uint256,uint256)", u256(100), u256(200)) == encodeArgs(u256(300)));
+ BOOST_CHECK(callContractFunction("div(uint256,uint256)", u256(2), u256(1)) == encodeArgs(u256(2)));
+ BOOST_CHECK(callContractFunction("div(uint256,uint256)", u256(200), u256(10)) == encodeArgs(u256(20)));
+ BOOST_CHECK(callContractFunction("div(uint256,uint256)", u256(1), u256(0)) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("div(uint256,uint256)", u256(0), u256(1)) == encodeArgs(u256(0)));
+}
+
+BOOST_AUTO_TEST_CASE(bitwise_shifting_constantinople)
+{
+ if (!dev::test::Options::get().evmVersion().hasBitwiseShifting())
+ return;
+ char const* sourceCode = R"(
+ contract C {
+ function shl(uint a, uint b) returns (uint c) {
+ assembly {
+ a
+ b
+ shl
+ =: c
+ }
+ }
+ function shr(uint a, uint b) returns (uint c) {
+ assembly {
+ a
+ b
+ shr
+ =: c
+ }
+ }
+ function sar(uint a, uint b) returns (uint c) {
+ assembly {
+ a
+ b
+ sar
+ =: c
+ }
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("shl(uint256,uint256)", u256(1), u256(2)) == encodeArgs(u256(4)));
+ BOOST_CHECK(callContractFunction("shl(uint256,uint256)", u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), u256(1)) == encodeArgs(u256("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe")));
+ BOOST_CHECK(callContractFunction("shl(uint256,uint256)", u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), u256(256)) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("shr(uint256,uint256)", u256(3), u256(1)) == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("shr(uint256,uint256)", u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), u256(1)) == encodeArgs(u256("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")));
+ BOOST_CHECK(callContractFunction("shr(uint256,uint256)", u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), u256(255)) == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("shr(uint256,uint256)", u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), u256(256)) == encodeArgs(u256(0)));
+ BOOST_CHECK(callContractFunction("sar(uint256,uint256)", u256(3), u256(1)) == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("sar(uint256,uint256)", u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), u256(1)) == encodeArgs(u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")));
+ BOOST_CHECK(callContractFunction("sar(uint256,uint256)", u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), u256(255)) == encodeArgs(u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")));
+ BOOST_CHECK(callContractFunction("sar(uint256,uint256)", u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), u256(256)) == encodeArgs(u256("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")));
+}
+
+BOOST_AUTO_TEST_CASE(bitwise_shifting_constants_constantinople)
+{
+ if (!dev::test::Options::get().evmVersion().hasBitwiseShifting())
+ return;
+ char const* sourceCode = R"(
+ contract C {
+ function shl_1() returns (bool) {
+ uint c;
+ assembly {
+ 1
+ 2
+ shl
+ =: c
+ }
+ assert(c == 4);
+ return true;
+ }
+ function shl_2() returns (bool) {
+ uint c;
+ assembly {
+ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ 1
+ shl
+ =: c
+ }
+ assert(c == 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe);
+ return true;
+ }
+ function shl_3() returns (bool) {
+ uint c;
+ assembly {
+ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ 256
+ shl
+ =: c
+ }
+ assert(c == 0);
+ return true;
+ }
+ function shr_1() returns (bool) {
+ uint c;
+ assembly {
+ 3
+ 1
+ shr
+ =: c
+ }
+ assert(c == 1);
+ return true;
+ }
+ function shr_2() returns (bool) {
+ uint c;
+ assembly {
+ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ 1
+ shr
+ =: c
+ }
+ assert(c == 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
+ return true;
+ }
+ function shr_3() returns (bool) {
+ uint c;
+ assembly {
+ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+ 256
+ shr
+ =: c
+ }
+ assert(c == 0);
+ return true;
+ }
+ }
+ )";
+ compileAndRun(sourceCode);
+ BOOST_CHECK(callContractFunction("shl_1()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("shl_2()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("shl_3()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("shr_1()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("shr_2()") == encodeArgs(u256(1)));
+ BOOST_CHECK(callContractFunction("shr_3()") == encodeArgs(u256(1)));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityExpressionCompiler.cpp b/test/libsolidity/SolidityExpressionCompiler.cpp
index 5f044b44..90d8265c 100644
--- a/test/libsolidity/SolidityExpressionCompiler.cpp
+++ b/test/libsolidity/SolidityExpressionCompiler.cpp
@@ -30,7 +30,7 @@
#include <libsolidity/ast/AST.h>
#include <libsolidity/analysis/TypeChecker.h>
#include <libsolidity/interface/ErrorReporter.h>
-#include "../TestHelper.h"
+#include <test/Options.h>
using namespace std;
@@ -503,12 +503,15 @@ BOOST_AUTO_TEST_CASE(blockhash)
char const* sourceCode = R"(
contract test {
function f() {
- block.blockhash(3);
+ blockhash(3);
}
}
)";
- bytes code = compileFirstExpression(sourceCode, {}, {},
- {make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::Block))});
+
+ auto blockhashFun = make_shared<FunctionType>(strings{"uint256"}, strings{"bytes32"},
+ FunctionType::Kind::BlockHash, false, StateMutability::View);
+
+ bytes code = compileFirstExpression(sourceCode, {}, {}, {make_shared<MagicVariableDeclaration>("blockhash", blockhashFun)});
bytes expectation({byte(Instruction::PUSH1), 0x03,
byte(Instruction::BLOCKHASH)});
diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp
index 997b610e..d438a9dc 100644
--- a/test/libsolidity/SolidityNameAndTypeResolution.cpp
+++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp
@@ -22,7 +22,7 @@
#include <test/libsolidity/AnalysisFramework.h>
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <libsolidity/ast/AST.h>
@@ -43,281 +43,6 @@ namespace test
BOOST_FIXTURE_TEST_SUITE(SolidityNameAndTypeResolution, AnalysisFramework)
-BOOST_AUTO_TEST_CASE(smoke_test)
-{
- char const* text = R"(
- contract test {
- uint256 stateVariable1;
- function fun(uint256 arg1) public { uint256 y; y = arg1; }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(double_stateVariable_declaration)
-{
- char const* text = R"(
- contract test {
- uint256 variable;
- uint128 variable;
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Identifier already declared.");
-}
-
-BOOST_AUTO_TEST_CASE(double_function_declaration)
-{
- char const* text = R"(
- contract test {
- function fun() public { }
- function fun() public { }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Function with same name and arguments defined twice.");
-}
-
-BOOST_AUTO_TEST_CASE(double_variable_declaration)
-{
- string text = R"(
- contract test {
- function f() pure public {
- uint256 x;
- if (true) { uint256 x; }
- }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Identifier already declared");
-}
-
-BOOST_AUTO_TEST_CASE(double_variable_declaration_050)
-{
- string text = R"(
- pragma experimental "v0.5.0";
- contract test {
- function f() pure public {
- uint256 x;
- if (true) { uint256 x; }
- }
- }
- )";
- CHECK_WARNING_ALLOW_MULTI(text, (vector<string>{
- "This declaration shadows an existing declaration.",
- "Unused local variable",
- "Unused local variable"
- }));
-}
-
-BOOST_AUTO_TEST_CASE(double_variable_declaration_disjoint_scope)
-{
- string text = R"(
- contract test {
- function f() pure public {
- { uint x; }
- { uint x; }
- }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Identifier already declared");
-}
-
-BOOST_AUTO_TEST_CASE(double_variable_declaration_disjoint_scope_050)
-{
- string text = R"(
- pragma experimental "v0.5.0";
- contract test {
- function f() pure public {
- { uint x; }
- { uint x; }
- }
- }
- )";
- CHECK_WARNING_ALLOW_MULTI(text, (vector<string>{
- "Unused local variable",
- "Unused local variable"
- }));
-}
-
-BOOST_AUTO_TEST_CASE(double_variable_declaration_disjoint_scope_activation)
-{
- string text = R"(
- contract test {
- function f() pure public {
- { uint x; }
- uint x;
- }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Identifier already declared");
-}
-
-BOOST_AUTO_TEST_CASE(double_variable_declaration_disjoint_scope_activation_050)
-{
- string text = R"(
- pragma experimental "v0.5.0";
- contract test {
- function f() pure public {
- { uint x; }
- uint x;
- }
- }
- )";
- CHECK_WARNING_ALLOW_MULTI(text, (vector<string>{
- "Unused local variable",
- "Unused local variable"
- }));
-}
-BOOST_AUTO_TEST_CASE(scoping_old)
-{
- char const* text = R"(
- contract test {
- function f() pure public {
- x = 4;
- uint256 x = 2;
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(scoping)
-{
- char const* text = R"(
- pragma experimental "v0.5.0";
- contract test {
- function f() public {
- {
- uint256 x;
- }
- x = 2;
- }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Undeclared identifier");
-}
-
-BOOST_AUTO_TEST_CASE(scoping_activation_old)
-{
- char const* text = R"(
- contract test {
- function f() pure public {
- x = 3;
- uint x;
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(scoping_activation)
-{
- char const* text = R"(
- pragma experimental "v0.5.0";
- contract test {
- function f() pure public {
- x = 3;
- uint x;
- }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Undeclared identifier");
-}
-
-BOOST_AUTO_TEST_CASE(scoping_self_use)
-{
- char const* text = R"(
- contract test {
- function f() pure public {
- uint a = a;
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(scoping_self_use_050)
-{
- char const* text = R"(
- pragma experimental "v0.5.0";
- contract test {
- function f() pure public {
- uint a = a;
- }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Undeclared identifier");
-}
-
-BOOST_AUTO_TEST_CASE(scoping_for)
-{
- char const* text = R"(
- pragma experimental "v0.5.0";
- contract test {
- function f() pure public {
- for (uint x = 0; x < 10; x ++){
- x = 2;
- }
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(scoping_for2)
-{
- char const* text = R"(
- pragma experimental "v0.5.0";
- contract test {
- function f() pure public {
- for (uint x = 0; x < 10; x ++)
- x = 2;
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(scoping_for3)
-{
- char const* text = R"(
- pragma experimental "v0.5.0";
- contract test {
- function f() pure public {
- for (uint x = 0; x < 10; x ++){
- x = 2;
- }
- x = 4;
- }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Undeclared identifier");
-}
-
-BOOST_AUTO_TEST_CASE(scoping_for_decl_in_body)
-{
- char const* text = R"(
- pragma experimental "v0.5.0";
- contract test {
- function f() pure public {
- for (;; y++){
- uint y = 3;
- }
- }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Undeclared identifier");
-}
-
-BOOST_AUTO_TEST_CASE(name_shadowing)
-{
- char const* text = R"(
- contract test {
- uint256 variable;
- function f() public { uint32 variable; variable = 2; }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
BOOST_AUTO_TEST_CASE(name_references)
{
char const* text = R"(
@@ -367,61 +92,6 @@ BOOST_AUTO_TEST_CASE(reference_to_later_declaration)
CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(struct_definition_directly_recursive)
-{
- char const* text = R"(
- contract test {
- struct MyStructName {
- address addr;
- MyStructName x;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Recursive struct definition.");
-}
-
-BOOST_AUTO_TEST_CASE(struct_definition_indirectly_recursive)
-{
- char const* text = R"(
- contract test {
- struct MyStructName1 {
- address addr;
- uint256 count;
- MyStructName2 x;
- }
- struct MyStructName2 {
- MyStructName1 x;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Recursive struct definition.");
-}
-
-BOOST_AUTO_TEST_CASE(struct_definition_not_really_recursive)
-{
- char const* text = R"(
- contract test {
- struct s1 { uint a; }
- struct s2 { s1 x; s1 y; }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(struct_definition_recursion_via_mapping)
-{
- char const* text = R"(
- contract test {
- struct MyStructName1 {
- address addr;
- uint256 count;
- mapping(uint => MyStructName1) x;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
BOOST_AUTO_TEST_CASE(type_inference_smoke_test)
{
char const* text = R"(
@@ -1237,6 +907,35 @@ BOOST_AUTO_TEST_CASE(base_constructor_arguments_override)
CHECK_SUCCESS(text);
}
+BOOST_AUTO_TEST_CASE(new_constructor_syntax)
+{
+ char const* text = R"(
+ contract A { constructor() public {} }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
+BOOST_AUTO_TEST_CASE(old_constructor_syntax)
+{
+ char const* text = R"(
+ contract A { function A() public {} }
+ )";
+ CHECK_WARNING(
+ text,
+ "Defining constructors as functions with the same name as the contract is deprecated."
+ );
+
+ text = R"(
+ pragma experimental "v0.5.0";
+ contract A { function A() public {} }
+ )";
+ CHECK_ERROR(
+ text,
+ SyntaxError,
+ "Functions are not allowed to have the same name as the contract."
+ );
+}
+
BOOST_AUTO_TEST_CASE(implicit_derived_to_base_conversion)
{
char const* text = R"(
@@ -1276,139 +975,6 @@ BOOST_AUTO_TEST_CASE(super_excludes_current_contract)
CHECK_ERROR(text, TypeError, "Member \"f\" not found or not visible after argument-dependent lookup in contract super B");
}
-BOOST_AUTO_TEST_CASE(function_modifier_invocation)
-{
- char const* text = R"(
- contract B {
- function f() mod1(2, true) mod2("0123456") pure public { }
- modifier mod1(uint a, bool b) { if (b) _; }
- modifier mod2(bytes7 a) { while (a == "1234567") _; }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(invalid_function_modifier_type)
-{
- char const* text = R"(
- contract B {
- function f() mod1(true) public { }
- modifier mod1(uint a) { if (a > 0) _; }
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid type for argument in modifier invocation. Invalid implicit conversion from bool to uint256 requested.");
-}
-
-BOOST_AUTO_TEST_CASE(function_modifier_invocation_parameters)
-{
- char const* text = R"(
- contract B {
- function f(uint8 a) mod1(a, true) mod2(r) public returns (bytes7 r) { }
- modifier mod1(uint a, bool b) { if (b) _; }
- modifier mod2(bytes7 a) { while (a == "1234567") _; }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables)
-{
- char const* text = R"(
- contract B {
- function f() mod(x) pure public { uint x = 7; }
- modifier mod(uint a) { if (a > 0) _; }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
-}
-
-BOOST_AUTO_TEST_CASE(function_modifier_invocation_local_variables050)
-{
- char const* text = R"(
- pragma experimental "v0.5.0";
- contract B {
- function f() mod(x) pure public { uint x = 7; }
- modifier mod(uint a) { if (a > 0) _; }
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Undeclared identifier.");
-}
-
-BOOST_AUTO_TEST_CASE(function_modifier_double_invocation)
-{
- char const* text = R"(
- contract B {
- function f(uint x) mod(x) mod(2) public { }
- modifier mod(uint a) { if (a > 0) _; }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(base_constructor_double_invocation)
-{
- char const* text = R"(
- contract C { function C(uint a) public {} }
- contract B is C {
- function B() C(2) C(2) public {}
- }
- )";
- CHECK_ERROR(text, DeclarationError, "Base constructor already provided");
-}
-
-BOOST_AUTO_TEST_CASE(legal_modifier_override)
-{
- char const* text = R"(
- contract A { modifier mod(uint a) { _; } }
- contract B is A { modifier mod(uint a) { _; } }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(illegal_modifier_override)
-{
- char const* text = R"(
- contract A { modifier mod(uint a) { _; } }
- contract B is A { modifier mod(uint8 a) { _; } }
- )";
- CHECK_ERROR(text, TypeError, "Override changes modifier signature.");
-}
-
-BOOST_AUTO_TEST_CASE(modifier_overrides_function)
-{
- char const* text = R"(
- contract A { modifier mod(uint a) { _; } }
- contract B is A { function mod(uint a) public { } }
- )";
- CHECK_ALLOW_MULTI(text, (vector<pair<Error::Type, string>>{
- {Error::Type::DeclarationError, "Identifier already declared"},
- {Error::Type::TypeError, "Override changes modifier to function"}
- }));
-}
-
-BOOST_AUTO_TEST_CASE(function_overrides_modifier)
-{
- char const* text = R"(
- contract A { function mod(uint a) public { } }
- contract B is A { modifier mod(uint a) { _; } }
- )";
- CHECK_ALLOW_MULTI(text, (vector<pair<Error::Type, string>>{
- {Error::Type::DeclarationError, "Identifier already declared"},
- {Error::Type::TypeError, "Override changes function to modifier"}
- }));
-}
-
-BOOST_AUTO_TEST_CASE(modifier_returns_value)
-{
- char const* text = R"(
- contract A {
- function f(uint a) mod(2) public returns (uint r) { }
- modifier mod(uint a) { _; return 7; }
- }
- )";
- CHECK_ERROR(text, TypeError, "Return arguments not allowed.");
-}
-
BOOST_AUTO_TEST_CASE(state_variable_accessors)
{
char const* text = R"(
@@ -2727,8 +2293,8 @@ BOOST_AUTO_TEST_CASE(test_fromElementaryTypeName)
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 31, 0)) == *make_shared<FixedBytesType>(31));
BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::BytesM, 32, 0)) == *make_shared<FixedBytesType>(32));
- BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Fixed, 0, 0)) == *make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Signed));
- BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UFixed, 0, 0)) == *make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Unsigned));
+ BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::Fixed, 0, 0)) == *make_shared<FixedPointType>(128, 18, FixedPointType::Modifier::Signed));
+ BOOST_CHECK(*Type::fromElementaryTypeName(ElementaryTypeNameToken(Token::UFixed, 0, 0)) == *make_shared<FixedPointType>(128, 18, FixedPointType::Modifier::Unsigned));
}
BOOST_AUTO_TEST_CASE(test_byte_is_alias_of_byte1)
@@ -3424,7 +2990,10 @@ BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
}
}
)";
- CHECK_ERROR(sourceCode, TypeError, "Explicit type conversion not allowed from \"inaccessible dynamic type\" to \"bytes storage pointer\".");
+ if (dev::test::Options::get().evmVersion() == EVMVersion::homestead())
+ CHECK_ERROR(sourceCode, TypeError, "Explicit type conversion not allowed from \"inaccessible dynamic type\" to \"bytes storage pointer\".");
+ else
+ CHECK_WARNING(sourceCode, "Use of the \"var\" keyword is deprecated");
}
BOOST_AUTO_TEST_CASE(memory_arrays_not_resizeable)
@@ -4474,21 +4043,6 @@ BOOST_AUTO_TEST_CASE(conditional_with_all_types)
CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(constructor_call_invalid_arg_count)
-{
- // This caused a segfault in an earlier version
- char const* text = R"(
- contract C {
- function C(){}
- }
- contract D is C {
- function D() C(5){}
- }
- )";
-
- CHECK_ERROR(text, TypeError, "Wrong argument count for modifier invocation: 1 arguments given but expected 0.");
-}
-
BOOST_AUTO_TEST_CASE(index_access_for_bytes)
{
char const* text = R"(
@@ -4743,7 +4297,7 @@ BOOST_AUTO_TEST_CASE(invalid_int_implicit_conversion_from_fixed)
}
}
)";
- CHECK_ERROR(text, TypeError, "Type fixed128x19 is not implicitly convertible to expected type int256");
+ CHECK_ERROR(text, TypeError, "Type fixed128x18 is not implicitly convertible to expected type int256");
}
BOOST_AUTO_TEST_CASE(rational_unary_operation)
@@ -4861,7 +4415,7 @@ BOOST_AUTO_TEST_CASE(fixed_type_invalid_implicit_conversion_size)
}
}
)";
- CHECK_ERROR(text, TypeError, "Type ufixed128x19 is not implicitly convertible to expected type ufixed248x8");
+ CHECK_ERROR(text, TypeError, "Type ufixed128x18 is not implicitly convertible to expected type ufixed248x8");
}
BOOST_AUTO_TEST_CASE(fixed_type_invalid_implicit_conversion_lost_data)
@@ -4948,7 +4502,7 @@ BOOST_AUTO_TEST_CASE(fixed_to_bytes_implicit_conversion)
}
}
)";
- CHECK_ERROR(text, TypeError, "fixed128x19 is not implicitly convertible to expected type bytes32");
+ CHECK_ERROR(text, TypeError, "fixed128x18 is not implicitly convertible to expected type bytes32");
}
BOOST_AUTO_TEST_CASE(mapping_with_fixed_literal)
@@ -5218,20 +4772,6 @@ BOOST_AUTO_TEST_CASE(integer_and_fixed_interaction)
CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(signed_rational_modulus)
-{
- char const* text = R"(
- contract test {
- function f() public {
- fixed a = 0.42578125 % -0.4271087646484375;
- fixed b = .5 % a;
- fixed c = a % b;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
BOOST_AUTO_TEST_CASE(one_divided_by_three_integer_conversion)
{
char const* text = R"(
@@ -5353,16 +4893,6 @@ BOOST_AUTO_TEST_CASE(no_warn_about_callcode_as_function)
CHECK_SUCCESS_NO_WARNINGS(text);
}
-BOOST_AUTO_TEST_CASE(modifier_without_underscore)
-{
- char const* text = R"(
- contract test {
- modifier m() {}
- }
- )";
- CHECK_ERROR(text, SyntaxError, "Modifier body does not contain '_'.");
-}
-
BOOST_AUTO_TEST_CASE(payable_in_library)
{
char const* text = R"(
@@ -5562,319 +5092,6 @@ BOOST_AUTO_TEST_CASE(using_directive_for_missing_selftype)
CHECK_ERROR(text, TypeError, "Member \"b\" not found or not visible after argument-dependent lookup in bytes memory");
}
-BOOST_AUTO_TEST_CASE(function_type)
-{
- char const* text = R"(
- contract C {
- function f() public {
- function(uint) returns (uint) x;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(function_type_parameter)
-{
- char const* text = R"(
- contract C {
- function f(function(uint) external returns (uint) g) public returns (function(uint) external returns (uint)) {
- return g;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(function_type_returned)
-{
- char const* text = R"(
- contract C {
- function f() public returns (function(uint) external returns (uint) g) {
- return g;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(private_function_type)
-{
- char const* text = R"(
- contract C {
- function f() public {
- function(uint) private returns (uint) x;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid visibility, can only be \"external\" or \"internal\".");
-}
-
-BOOST_AUTO_TEST_CASE(public_function_type)
-{
- char const* text = R"(
- contract C {
- function f() public {
- function(uint) public returns (uint) x;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid visibility, can only be \"external\" or \"internal\".");
-}
-
-BOOST_AUTO_TEST_CASE(payable_internal_function_type)
-{
- char const* text = R"(
- contract C {
- function (uint) internal payable returns (uint) x;
- }
- )";
- CHECK_ERROR(text, TypeError, "Only external function types can be payable.");
-}
-
-BOOST_AUTO_TEST_CASE(payable_internal_function_type_is_not_fatal)
-{
- char const* text = R"(
- contract C {
- function (uint) internal payable returns (uint) x;
-
- function g() {
- x = g;
- }
- }
- )";
- CHECK_ERROR_ALLOW_MULTI(text, TypeError, (std::vector<std::string>{"Only external function types can be payable."}));
-}
-
-BOOST_AUTO_TEST_CASE(call_value_on_non_payable_function_type)
-{
- char const* text = R"(
- contract C {
- function (uint) external returns (uint) x;
- function f() public {
- x.value(2)();
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Member \"value\" not found or not visible after argument-dependent lookup in function (uint256) external returns (uint256) - did you forget the \"payable\" modifier?");
-}
-
-BOOST_AUTO_TEST_CASE(external_function_type_returning_internal)
-{
- char const* text = R"(
- contract C {
- function() external returns (function () internal) x;
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal type cannot be used for external function type.");
-}
-
-BOOST_AUTO_TEST_CASE(external_function_type_taking_internal)
-{
- char const* text = R"(
- contract C {
- function(function () internal) external x;
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal type cannot be used for external function type.");
-}
-
-BOOST_AUTO_TEST_CASE(call_value_on_payable_function_type)
-{
- char const* text = R"(
- contract C {
- function (uint) external payable returns (uint) x;
- function f() public {
- x.value(2)(1);
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter)
-{
- // It should not be possible to give internal functions
- // as parameters to external functions.
- char const* text = R"(
- contract C {
- function f(function(uint) internal returns (uint) x) public {
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
-}
-
-BOOST_AUTO_TEST_CASE(internal_function_returned_from_public_function)
-{
- // It should not be possible to return internal functions from external functions.
- char const* text = R"(
- contract C {
- function f() public returns (function(uint) internal returns (uint) x) {
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
-}
-
-BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_internal)
-{
- char const* text = R"(
- library L {
- function f(function(uint) internal returns (uint) x) internal {
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(internal_function_as_external_parameter_in_library_external)
-{
- char const* text = R"(
- library L {
- function f(function(uint) internal returns (uint) x) public {
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
-}
-
-BOOST_AUTO_TEST_CASE(function_type_arrays)
-{
- char const* text = R"(
- contract C {
- function(uint) external returns (uint)[] public x;
- function(uint) internal returns (uint)[10] y;
- function f() public {
- function(uint) returns (uint)[10] memory a;
- function(uint) returns (uint)[10] storage b = y;
- function(uint) external returns (uint)[] memory c;
- c = new function(uint) external returns (uint)[](200);
- a; b;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(delete_function_type)
-{
- char const* text = R"(
- contract C {
- function(uint) external returns (uint) x;
- function(uint) internal returns (uint) y;
- function f() public {
- delete x;
- var a = y;
- delete a;
- delete y;
- var c = f;
- delete c;
- function(uint) internal returns (uint) g;
- delete g;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(delete_function_type_invalid)
-{
- char const* text = R"(
- contract C {
- function f() public {
- delete f;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Expression has to be an lvalue.");
-}
-
-BOOST_AUTO_TEST_CASE(delete_external_function_type_invalid)
-{
- char const* text = R"(
- contract C {
- function f() public {
- delete this.f;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Expression has to be an lvalue.");
-}
-
-BOOST_AUTO_TEST_CASE(external_function_to_function_type_calldata_parameter)
-{
- // This is a test that checks that the type of the `bytes` parameter is
- // correctly changed from its own type `bytes calldata` to `bytes memory`
- // when converting to a function type.
- char const* text = R"(
- contract C {
- function f(function(bytes memory) external g) public { }
- function callback(bytes) external {}
- function g() public {
- f(this.callback);
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(external_function_type_to_address)
-{
- char const* text = R"(
- contract C {
- function f() public returns (address) {
- return address(this.f);
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(internal_function_type_to_address)
-{
- char const* text = R"(
- contract C {
- function f() public returns (address) {
- return address(f);
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Explicit type conversion not allowed");
-}
-
-BOOST_AUTO_TEST_CASE(external_function_type_to_uint)
-{
- char const* text = R"(
- contract C {
- function f() public returns (uint) {
- return uint(this.f);
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Explicit type conversion not allowed");
-}
-
-BOOST_AUTO_TEST_CASE(warn_function_type_parameters_with_names)
-{
- char const* text = R"(
- contract C {
- function(uint a) f;
- }
- )";
- CHECK_WARNING(text, "Naming function type parameters is deprecated.");
-}
-
-BOOST_AUTO_TEST_CASE(warn_function_type_return_parameters_with_names)
-{
- char const* text = R"(
- contract C {
- function(uint) returns (bool ret) f;
- }
- )";
- CHECK_WARNING(text, "Naming function type return parameters is deprecated.");
-}
-
BOOST_AUTO_TEST_CASE(shift_constant_left_negative_rvalue)
{
char const* text = R"(
@@ -5915,6 +5132,16 @@ BOOST_AUTO_TEST_CASE(shift_constant_right_excessive_rvalue)
CHECK_ERROR(text, TypeError, "Operator >> not compatible with types int_const 66 and int_const 4294967296");
}
+BOOST_AUTO_TEST_CASE(shift_constant_right_fractional)
+{
+ char const* text = R"(
+ contract C {
+ uint public a = 0x42 >> (1 / 2);
+ }
+ )";
+ CHECK_ERROR(text, TypeError, "Operator >> not compatible with types int_const 66 and rational_const 1 / 2");
+}
+
BOOST_AUTO_TEST_CASE(inline_assembly_unbalanced_positive_stack)
{
char const* text = R"(
@@ -6439,43 +5666,22 @@ BOOST_AUTO_TEST_CASE(return_structs)
CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(return_recursive_structs)
-{
- char const* text = R"(
- contract C {
- struct S { uint a; S[] sub; }
- function f() returns (uint, S) {
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
-}
-
-BOOST_AUTO_TEST_CASE(return_recursive_structs2)
+BOOST_AUTO_TEST_CASE(read_returned_struct)
{
char const* text = R"(
- contract C {
- struct S { uint a; S[2][] sub; }
- function f() returns (uint, S) {
+ pragma experimental ABIEncoderV2;
+ contract A {
+ struct T {
+ int x;
+ int y;
}
- }
- )";
- CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
-}
-
-BOOST_AUTO_TEST_CASE(return_recursive_structs3)
-{
- char const* text = R"(
- contract C {
- struct S { uint a; S[][][] sub; }
- struct T { S s; }
- function f() returns (uint x, T t) {
+ function g() public returns (T) {
+ return this.g();
}
}
)";
- CHECK_ERROR(text, TypeError, "Internal or recursive type is not allowed for public or external functions.");
+ CHECK_WARNING(text, "Experimental features");
}
-
BOOST_AUTO_TEST_CASE(address_checksum_type_deduction)
{
char const* text = R"(
@@ -6598,38 +5804,6 @@ BOOST_AUTO_TEST_CASE(address_methods)
CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(cyclic_dependency_for_constants)
-{
- char const* text = R"(
- contract C {
- uint constant a = a;
- }
- )";
- CHECK_ERROR(text, TypeError, "cyclic dependency via a");
- text = R"(
- contract C {
- uint constant a = b * c;
- uint constant b = 7;
- uint constant c = b + uint(keccak256(d));
- uint constant d = 2 + a;
- }
- )";
- CHECK_ERROR_ALLOW_MULTI(text, TypeError, (std::vector<std::string>{
- "a has a cyclic dependency via c",
- "c has a cyclic dependency via d",
- "d has a cyclic dependency via a"
- }));
- text = R"(
- contract C {
- uint constant a = b * c;
- uint constant b = 7;
- uint constant c = 4 + uint(keccak256(d));
- uint constant d = 2 + b;
- }
- )";
- CHECK_SUCCESS(text);
-}
-
BOOST_AUTO_TEST_CASE(interface)
{
char const* text = R"(
@@ -6674,54 +5848,6 @@ BOOST_AUTO_TEST_CASE(interface_function_bodies)
CHECK_ERROR(text, TypeError, "Functions in interfaces cannot have an implementation");
}
-BOOST_AUTO_TEST_CASE(interface_function_external)
-{
- char const* text = R"(
- pragma experimental "v0.5.0";
- interface I {
- function f() external;
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(interface_function_public)
-{
- char const* text = R"(
- interface I {
- function f() public;
- }
- )";
- CHECK_WARNING(text, "Functions in interfaces should be declared external.");
- text = R"(
- pragma experimental "v0.5.0";
- interface I {
- function f() public;
- }
- )";
- CHECK_ERROR(text, TypeError, "Functions in interfaces must be declared external.");
-}
-
-BOOST_AUTO_TEST_CASE(interface_function_internal)
-{
- char const* text = R"(
- interface I {
- function f() internal;
- }
- )";
- CHECK_ERROR(text, TypeError, "Functions in interfaces cannot be internal or private.");
-}
-
-BOOST_AUTO_TEST_CASE(interface_function_private)
-{
- char const* text = R"(
- interface I {
- function f() private;
- }
- )";
- CHECK_ERROR(text, TypeError, "Functions in interfaces cannot be internal or private.");
-}
-
BOOST_AUTO_TEST_CASE(interface_events)
{
char const* text = R"(
@@ -6816,6 +5942,20 @@ BOOST_AUTO_TEST_CASE(using_interface_complex)
CHECK_SUCCESS(text);
}
+BOOST_AUTO_TEST_CASE(interface_implement_public_contract)
+{
+ char const* text = R"(
+ interface I {
+ function f() external;
+ }
+ contract C is I {
+ function f() public {
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
+}
+
BOOST_AUTO_TEST_CASE(warn_about_throw)
{
char const* text = R"(
@@ -6847,14 +5987,30 @@ BOOST_AUTO_TEST_CASE(bare_revert)
}
}
)";
- CHECK_WARNING(text, "Statement has no effect.");
+ CHECK_ERROR(text, TypeError, "No matching declaration found");
+}
+
+BOOST_AUTO_TEST_CASE(revert_with_reason)
+{
+ char const* text = R"(
+ contract C {
+ function f(uint x) pure public {
+ if (x > 7)
+ revert("abc");
+ else
+ revert();
+ }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(text);
}
BOOST_AUTO_TEST_CASE(bare_others)
{
CHECK_WARNING("contract C { function f() pure public { selfdestruct; } }", "Statement has no effect.");
CHECK_WARNING("contract C { function f() pure public { assert; } }", "Statement has no effect.");
- CHECK_WARNING("contract C { function f() pure public { require; } }", "Statement has no effect.");
+ // This is different because it does have overloads.
+ CHECK_ERROR("contract C { function f() pure public { require; } }", TypeError, "No matching declaration found after variable lookup.");
CHECK_WARNING("contract C { function f() pure public { suicide; } }", "Statement has no effect.");
}
@@ -7195,7 +6351,7 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_ignores_constructor)
{
char const* text = R"(
contract C {
- function C() public {}
+ constructor() public {}
}
)";
CHECK_SUCCESS_NO_WARNINGS(text);
@@ -7353,7 +6509,7 @@ BOOST_AUTO_TEST_CASE(does_not_error_transfer_regular_function)
CHECK_SUCCESS_NO_WARNINGS(text);
}
-BOOST_AUTO_TEST_CASE(returndatacopy_as_variable)
+BOOST_AUTO_TEST_CASE(returndatasize_as_variable)
{
char const* text = R"(
contract c { function f() public { uint returndatasize; assembly { returndatasize }}}
@@ -7520,7 +6676,7 @@ BOOST_AUTO_TEST_CASE(modifiers_access_storage_pointer)
{
char const* text = R"(
contract C {
- struct S { }
+ struct S { uint a; }
modifier m(S storage x) {
x;
_;
@@ -7607,7 +6763,7 @@ BOOST_AUTO_TEST_CASE(using_this_in_constructor)
{
char const* text = R"(
contract C {
- function C() public {
+ constructor() public {
this.f();
}
function f() pure public {
@@ -7921,53 +7077,6 @@ BOOST_AUTO_TEST_CASE(reject_interface_constructors)
CHECK_ERROR(text, TypeError, "Wrong argument count for constructor call: 1 arguments given but expected 0.");
}
-BOOST_AUTO_TEST_CASE(tight_packing_literals)
-{
- char const* text = R"(
- contract C {
- function f() pure public returns (bytes32) {
- return keccak256(1);
- }
- }
- )";
- CHECK_WARNING(text, "The type of \"int_const 1\" was inferred as uint8.");
- text = R"(
- contract C {
- function f() pure public returns (bytes32) {
- return keccak256(uint8(1));
- }
- }
- )";
- CHECK_SUCCESS_NO_WARNINGS(text);
- text = R"(
- contract C {
- function f() pure public returns (bytes32) {
- return sha3(1);
- }
- }
- )";
- CHECK_WARNING_ALLOW_MULTI(text, (std::vector<std::string>{
- "The type of \"int_const 1\" was inferred as uint8.",
- "\"sha3\" has been deprecated in favour of \"keccak256\""
- }));
- text = R"(
- contract C {
- function f() pure public returns (bytes32) {
- return sha256(1);
- }
- }
- )";
- CHECK_WARNING(text, "The type of \"int_const 1\" was inferred as uint8.");
- text = R"(
- contract C {
- function f() pure public returns (bytes32) {
- return ripemd160(1);
- }
- }
- )";
- CHECK_WARNING(text, "The type of \"int_const 1\" was inferred as uint8.");
-}
-
BOOST_AUTO_TEST_CASE(non_external_fallback)
{
char const* text = R"(
@@ -8095,171 +7204,6 @@ BOOST_AUTO_TEST_CASE(address_overload_resolution)
CHECK_SUCCESS(text);
}
-BOOST_AUTO_TEST_CASE(array_length_too_large)
-{
- char const* text = R"(
- contract C {
- uint[8**90] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_not_convertible_to_integer)
-{
- char const* text = R"(
- contract C {
- uint[true] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_constant_var)
-{
- char const* text = R"(
- contract C {
- uint constant LEN = 10;
- uint[LEN] ids;
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(array_length_non_integer_constant_var)
-{
- char const* text = R"(
- contract C {
- bool constant LEN = true;
- uint[LEN] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_cannot_be_function)
-{
- char const* text = R"(
- contract C {
- function f() {}
- uint[f] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_can_be_recursive_constant)
-{
- char const* text = R"(
- contract C {
- uint constant L = 5;
- uint constant LEN = L + 4 * L;
- uint[LEN] ids;
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(array_length_cannot_be_function_call)
-{
- char const* text = R"(
- contract C {
- function f(uint x) {}
- uint constant LEN = f();
- uint[LEN] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_const_cannot_be_fractional)
-{
- char const* text = R"(
- contract C {
- fixed constant L = 10.5;
- uint[L] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Array with fractional length specified");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_can_be_constant_in_struct)
-{
- char const* text = R"(
- contract C {
- uint constant LEN = 10;
- struct Test {
- uint[LEN] ids;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(array_length_can_be_constant_in_function)
-{
- char const* text = R"(
- contract C {
- uint constant LEN = 10;
- function f() {
- uint[LEN] a;
- }
- }
- )";
- CHECK_SUCCESS(text);
-}
-
-BOOST_AUTO_TEST_CASE(array_length_cannot_be_constant_function_parameter)
-{
- char const* text = R"(
- contract C {
- function f(uint constant LEN) {
- uint[LEN] a;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_with_cyclic_constant)
-{
- char const* text = R"(
- contract C {
- uint constant LEN = LEN;
- function f() {
- uint[LEN] a;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Cyclic constant definition (or maximum recursion depth exhausted).");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_with_complex_cyclic_constant)
-{
- char const* text = R"(
- contract C {
- uint constant L2 = LEN - 10;
- uint constant L1 = L2 / 10;
- uint constant LEN = 10 + L1 * 5;
- function f() {
- uint[LEN] a;
- }
- }
- )";
- CHECK_ERROR(text, TypeError, "Cyclic constant definition (or maximum recursion depth exhausted).");
-}
-
-BOOST_AUTO_TEST_CASE(array_length_with_pure_functions)
-{
- char const* text = R"(
- contract C {
- uint constant LEN = keccak256(ripemd160(33));
- uint[LEN] ids;
- }
- )";
- CHECK_ERROR(text, TypeError, "Invalid array length, expected integer literal or constant expression.");
-}
-
BOOST_AUTO_TEST_CASE(array_length_invalid_expression)
{
char const* text = R"(
@@ -8587,6 +7531,33 @@ BOOST_AUTO_TEST_CASE(require_visibility_specifiers)
CHECK_ERROR(text, SyntaxError, "No visibility specified.");
}
+BOOST_AUTO_TEST_CASE(blockhash)
+{
+ char const* code = R"(
+ contract C {
+ function f() public view returns (bytes32) {
+ return block.blockhash(3);
+ }
+ }
+ )";
+ CHECK_WARNING(code, "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"");
+
+ code = R"(
+ contract C {
+ function f() public view returns (bytes32) { return blockhash(3); }
+ }
+ )";
+ CHECK_SUCCESS_NO_WARNINGS(code);
+
+ code = R"(
+ pragma experimental "v0.5.0";
+ contract C {
+ function f() public returns (bytes32) { return block.blockhash(3); }
+ }
+ )";
+ CHECK_ERROR(code, TypeError, "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\"");
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityNatspecJSON.cpp b/test/libsolidity/SolidityNatspecJSON.cpp
index 49a725e0..eeebeb74 100644
--- a/test/libsolidity/SolidityNatspecJSON.cpp
+++ b/test/libsolidity/SolidityNatspecJSON.cpp
@@ -20,7 +20,7 @@
* Unit tests for the solidity compiler JSON Interface output.
*/
-#include "../TestHelper.h"
+#include <test/Options.h>
#include <string>
#include <libdevcore/JSON.h>
#include <libsolidity/interface/CompilerStack.h>
diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp
index 33039ca9..5326feaf 100644
--- a/test/libsolidity/SolidityOptimizer.cpp
+++ b/test/libsolidity/SolidityOptimizer.cpp
@@ -74,11 +74,11 @@ public:
unsigned const _optimizeRuns = 200
)
{
- bytes nonOptimizedBytecode = compileAndRunWithOptimizer(_sourceCode, _value, _contractName, false, _optimizeRuns);
+ m_nonOptimizedBytecode = compileAndRunWithOptimizer(_sourceCode, _value, _contractName, false, _optimizeRuns);
m_nonOptimizedContract = m_contractAddress;
- bytes optimizedBytecode = compileAndRunWithOptimizer(_sourceCode, _value, _contractName, true, _optimizeRuns);
- size_t nonOptimizedSize = numInstructions(nonOptimizedBytecode);
- size_t optimizedSize = numInstructions(optimizedBytecode);
+ m_optimizedBytecode = compileAndRunWithOptimizer(_sourceCode, _value, _contractName, true, _optimizeRuns);
+ size_t nonOptimizedSize = numInstructions(m_nonOptimizedBytecode);
+ size_t optimizedSize = numInstructions(m_optimizedBytecode);
BOOST_CHECK_MESSAGE(
_optimizeRuns < 50 || optimizedSize < nonOptimizedSize,
string("Optimizer did not reduce bytecode size. Non-optimized size: ") +
@@ -93,8 +93,10 @@ public:
{
m_contractAddress = m_nonOptimizedContract;
bytes nonOptimizedOutput = callContractFunction(_sig, _arguments...);
+ m_gasUsedNonOptimized = m_gasUsed;
m_contractAddress = m_optimizedContract;
bytes optimizedOutput = callContractFunction(_sig, _arguments...);
+ m_gasUsedOptimized = m_gasUsed;
BOOST_CHECK_MESSAGE(!optimizedOutput.empty(), "No optimized output for " + _sig);
BOOST_CHECK_MESSAGE(!nonOptimizedOutput.empty(), "No un-optimized output for " + _sig);
BOOST_CHECK_MESSAGE(nonOptimizedOutput == optimizedOutput, "Computed values do not match."
@@ -104,7 +106,7 @@ public:
/// @returns the number of intructions in the given bytecode, not taking the metadata hash
/// into account.
- size_t numInstructions(bytes const& _bytecode)
+ size_t numInstructions(bytes const& _bytecode, boost::optional<Instruction> _which = boost::optional<Instruction>{})
{
BOOST_REQUIRE(_bytecode.size() > 5);
size_t metadataSize = (_bytecode[_bytecode.size() - 2] << 8) + _bytecode[_bytecode.size() - 1];
@@ -112,13 +114,18 @@ public:
BOOST_REQUIRE(_bytecode.size() >= metadataSize + 2);
bytes realCode = bytes(_bytecode.begin(), _bytecode.end() - metadataSize - 2);
size_t instructions = 0;
- solidity::eachInstruction(realCode, [&](Instruction, u256 const&) {
- instructions++;
+ solidity::eachInstruction(realCode, [&](Instruction _instr, u256 const&) {
+ if (!_which || *_which == _instr)
+ instructions++;
});
return instructions;
}
protected:
+ u256 m_gasUsedOptimized;
+ u256 m_gasUsedNonOptimized;
+ bytes m_nonOptimizedBytecode;
+ bytes m_optimizedBytecode;
Address m_optimizedContract;
Address m_nonOptimizedContract;
};
@@ -581,6 +588,49 @@ BOOST_AUTO_TEST_CASE(invalid_state_at_control_flow_join)
compareVersions("test()");
}
+BOOST_AUTO_TEST_CASE(init_empty_dynamic_arrays)
+{
+ // This is not so much an optimizer test, but rather a test
+ // that allocating empty arrays is implemented efficiently.
+ // In particular, initializing a dynamic memory array does
+ // not use any memory.
+ char const* sourceCode = R"(
+ contract Test {
+ function f() pure returns (uint r) {
+ uint[][] memory x = new uint[][](20000);
+ return x.length;
+ }
+ }
+ )";
+ compileBothVersions(sourceCode);
+ compareVersions("f()");
+ BOOST_CHECK_LE(m_gasUsedNonOptimized, 1900000);
+ BOOST_CHECK_LE(1600000, m_gasUsedNonOptimized);
+}
+
+BOOST_AUTO_TEST_CASE(optimise_multi_stores)
+{
+ char const* sourceCode = R"(
+ contract Test {
+ struct S { uint16 a; uint16 b; uint16[3] c; uint[] dyn; }
+ uint padding;
+ S[] s;
+ function f() public returns (uint16, uint16, uint16[3], uint) {
+ uint16[3] memory c;
+ c[0] = 7;
+ c[1] = 8;
+ c[2] = 9;
+ s.push(S(1, 2, c, new uint[](4)));
+ return (s[0].a, s[0].b, s[0].c, s[0].dyn[2]);
+ }
+ }
+ )";
+ compileBothVersions(sourceCode);
+ compareVersions("f()");
+ BOOST_CHECK_EQUAL(numInstructions(m_nonOptimizedBytecode, Instruction::SSTORE), 9);
+ BOOST_CHECK_EQUAL(numInstructions(m_optimizedBytecode, Instruction::SSTORE), 8);
+}
+
BOOST_AUTO_TEST_SUITE_END()
}
diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp
index f03b30e1..100b3662 100644
--- a/test/libsolidity/SolidityParser.cpp
+++ b/test/libsolidity/SolidityParser.cpp
@@ -25,8 +25,8 @@
#include <libsolidity/parsing/Scanner.h>
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/interface/ErrorReporter.h>
-#include "../TestHelper.h"
-#include "ErrorCheck.h"
+#include <test/Options.h>
+#include <test/libsolidity/ErrorCheck.h>
using namespace std;
@@ -112,26 +112,6 @@ while(0)
BOOST_AUTO_TEST_SUITE(SolidityParser)
-BOOST_AUTO_TEST_CASE(smoke_test)
-{
- char const* text = R"(
- contract test {
- uint256 stateVariable1;
- }
- )";
- BOOST_CHECK(successParse(text));
-}
-
-BOOST_AUTO_TEST_CASE(missing_variable_name_in_declaration)
-{
- char const* text = R"(
- contract test {
- uint256 ;
- }
- )";
- CHECK_PARSE_ERROR(text, "Expected identifier");
-}
-
BOOST_AUTO_TEST_CASE(empty_function)
{
char const* text = R"(
@@ -577,16 +557,6 @@ BOOST_AUTO_TEST_CASE(variable_definition_with_initialization)
BOOST_CHECK(successParse(text));
}
-BOOST_AUTO_TEST_CASE(variable_definition_in_function_parameter)
-{
- char const* text = R"(
- contract test {
- function fun(var a) {}
- }
- )";
- CHECK_PARSE_ERROR(text, "Expected explicit type name");
-}
-
BOOST_AUTO_TEST_CASE(variable_definition_in_mapping)
{
char const* text = R"(
@@ -599,18 +569,6 @@ BOOST_AUTO_TEST_CASE(variable_definition_in_mapping)
CHECK_PARSE_ERROR(text, "Expected elementary type name for mapping key type");
}
-BOOST_AUTO_TEST_CASE(variable_definition_in_function_return)
-{
- char const* text = R"(
- contract test {
- function fun() returns(var d) {
- return 1;
- }
- }
- )";
- CHECK_PARSE_ERROR(text, "Expected explicit type name");
-}
-
BOOST_AUTO_TEST_CASE(operator_expression)
{
char const* text = R"(
diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp
index bc9f2fe1..738b24bc 100644
--- a/test/libsolidity/SolidityTypes.cpp
+++ b/test/libsolidity/SolidityTypes.cpp
@@ -123,6 +123,7 @@ BOOST_AUTO_TEST_CASE(type_identifiers)
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bytes32")->identifier(), "t_bytes32");
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bool")->identifier(), "t_bool");
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bytes")->identifier(), "t_bytes_storage_ptr");
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bytes memory")->identifier(), "t_bytes_memory_ptr");
BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("string")->identifier(), "t_string_storage_ptr");
ArrayType largeintArray(DataLocation::Memory, Type::fromElementaryTypeName("int128"), u256("2535301200456458802993406410752"));
BOOST_CHECK_EQUAL(largeintArray.identifier(), "t_array$_t_int128_$2535301200456458802993406410752_memory_ptr");
diff --git a/test/libsolidity/StandardCompiler.cpp b/test/libsolidity/StandardCompiler.cpp
index 4c8918be..74bf01b2 100644
--- a/test/libsolidity/StandardCompiler.cpp
+++ b/test/libsolidity/StandardCompiler.cpp
@@ -261,19 +261,24 @@ BOOST_AUTO_TEST_CASE(basic_compilation)
BOOST_CHECK(contract["evm"]["bytecode"]["object"].isString());
BOOST_CHECK_EQUAL(
dev::test::bytecodeSansMetadata(contract["evm"]["bytecode"]["object"].asString()),
- "60606040523415600e57600080fd5b603580601b6000396000f3006060604052600080fd00"
+ "6080604052348015600f57600080fd5b50603580601d6000396000f3006080604052600080fd00"
);
BOOST_CHECK(contract["evm"]["assembly"].isString());
BOOST_CHECK(contract["evm"]["assembly"].asString().find(
- " /* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x60)\n jumpi(tag_1, iszero(callvalue))\n"
- " 0x0\n dup1\n revert\ntag_1:\n dataSize(sub_0)\n dup1\n dataOffset(sub_0)\n 0x0\n codecopy\n 0x0\n"
- " return\nstop\n\nsub_0: assembly {\n /* \"fileA\":0:14 contract A { } */\n"
- " mstore(0x40, 0x60)\n 0x0\n dup1\n revert\n\n"
- " auxdata: 0xa165627a7a7230582") == 0);
+ " /* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n "
+ "callvalue\n /* \"--CODEGEN--\":8:17 */\n dup1\n "
+ "/* \"--CODEGEN--\":5:7 */\n iszero\n tag_1\n jumpi\n "
+ "/* \"--CODEGEN--\":30:31 */\n 0x0\n /* \"--CODEGEN--\":27:28 */\n "
+ "dup1\n /* \"--CODEGEN--\":20:32 */\n revert\n /* \"--CODEGEN--\":5:7 */\n"
+ "tag_1:\n /* \"fileA\":0:14 contract A { } */\n pop\n dataSize(sub_0)\n dup1\n "
+ "dataOffset(sub_0)\n 0x0\n codecopy\n 0x0\n return\nstop\n\nsub_0: assembly {\n "
+ "/* \"fileA\":0:14 contract A { } */\n mstore(0x40, 0x80)\n 0x0\n "
+ "dup1\n revert\n\n auxdata: 0xa165627a7a72305820"
+ ) == 0);
BOOST_CHECK(contract["evm"]["gasEstimates"].isObject());
BOOST_CHECK_EQUAL(
dev::jsonCompactPrint(contract["evm"]["gasEstimates"]),
- "{\"creation\":{\"codeDepositCost\":\"10600\",\"executionCost\":\"61\",\"totalCost\":\"10661\"}}"
+ "{\"creation\":{\"codeDepositCost\":\"10600\",\"executionCost\":\"66\",\"totalCost\":\"10666\"}}"
);
BOOST_CHECK(contract["metadata"].isString());
BOOST_CHECK(dev::test::isValidMetadata(contract["metadata"].asString()));
@@ -752,6 +757,8 @@ BOOST_AUTO_TEST_CASE(evm_version)
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"spuriousDragon\"") != string::npos);
result = compile(inputForVersion("\"evmVersion\": \"byzantium\","));
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"byzantium\"") != string::npos);
+ result = compile(inputForVersion("\"evmVersion\": \"constantinople\","));
+ BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"constantinople\"") != string::npos);
// test default
result = compile(inputForVersion(""));
BOOST_CHECK(result["contracts"]["fileA"]["A"]["metadata"].asString().find("\"evmVersion\":\"byzantium\"") != string::npos);
diff --git a/test/libsolidity/SyntaxTest.cpp b/test/libsolidity/SyntaxTest.cpp
new file mode 100644
index 00000000..1c2355d5
--- /dev/null
+++ b/test/libsolidity/SyntaxTest.cpp
@@ -0,0 +1,283 @@
+/*
+ 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/>.
+*/
+
+#include <test/libsolidity/SyntaxTest.h>
+#include <test/Options.h>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+#include <boost/throw_exception.hpp>
+#include <cctype>
+#include <fstream>
+#include <memory>
+#include <stdexcept>
+
+using namespace dev;
+using namespace solidity;
+using namespace dev::solidity::test;
+using namespace dev::solidity::test::formatting;
+using namespace std;
+namespace fs = boost::filesystem;
+using namespace boost::unit_test;
+
+template<typename IteratorType>
+void skipWhitespace(IteratorType& _it, IteratorType _end)
+{
+ while (_it != _end && isspace(*_it))
+ ++_it;
+}
+
+template<typename IteratorType>
+void skipSlashes(IteratorType& _it, IteratorType _end)
+{
+ while (_it != _end && *_it == '/')
+ ++_it;
+}
+
+void expect(string::iterator& _it, string::iterator _end, string::value_type _c)
+{
+ if (_it == _end || *_it != _c)
+ throw runtime_error(string("Invalid test expectation. Expected: \"") + _c + "\".");
+ ++_it;
+}
+
+int parseUnsignedInteger(string::iterator &_it, string::iterator _end)
+{
+ if (_it == _end || !isdigit(*_it))
+ throw runtime_error("Invalid test expectation. Source location expected.");
+ int result = 0;
+ while (_it != _end && isdigit(*_it))
+ {
+ result *= 10;
+ result += *_it - '0';
+ ++_it;
+ }
+ return result;
+}
+
+SyntaxTest::SyntaxTest(string const& _filename)
+{
+ ifstream file(_filename);
+ if (!file)
+ BOOST_THROW_EXCEPTION(runtime_error("Cannot open test contract: \"" + _filename + "\"."));
+ file.exceptions(ios::badbit);
+
+ m_source = parseSource(file);
+ m_expectations = parseExpectations(file);
+}
+
+bool SyntaxTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted)
+{
+ string const versionPragma = "pragma solidity >=0.0;\n";
+ m_compiler.reset();
+ m_compiler.addSource("", versionPragma + m_source);
+ m_compiler.setEVMVersion(dev::test::Options::get().evmVersion());
+
+ if (m_compiler.parse())
+ m_compiler.analyze();
+
+ for (auto const& currentError: filterErrors(m_compiler.errors(), true))
+ {
+ int locationStart = -1, locationEnd = -1;
+ if (auto location = boost::get_error_info<errinfo_sourceLocation>(*currentError))
+ {
+ // ignore the version pragma inserted by the testing tool when calculating locations.
+ if (location->start >= static_cast<int>(versionPragma.size()))
+ locationStart = location->start - versionPragma.size();
+ if (location->end >= static_cast<int>(versionPragma.size()))
+ locationEnd = location->end - versionPragma.size();
+ }
+ m_errorList.emplace_back(SyntaxTestError{
+ currentError->typeName(),
+ errorMessage(*currentError),
+ locationStart,
+ locationEnd
+ });
+ }
+
+ if (m_expectations != m_errorList)
+ {
+ string nextIndentLevel = _linePrefix + " ";
+ FormattedScope(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
+ printErrorList(_stream, m_expectations, nextIndentLevel, _formatted);
+ FormattedScope(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Obtained result:" << endl;
+ printErrorList(_stream, m_errorList, nextIndentLevel, _formatted);
+ return false;
+ }
+ return true;
+}
+
+void SyntaxTest::printErrorList(
+ ostream& _stream,
+ vector<SyntaxTestError> const& _errorList,
+ string const& _linePrefix,
+ bool const _formatted
+)
+{
+ if (_errorList.empty())
+ FormattedScope(_stream, _formatted, {BOLD, GREEN}) << _linePrefix << "Success" << endl;
+ else
+ for (auto const& error: _errorList)
+ {
+ {
+ FormattedScope scope(_stream, _formatted, {BOLD, (error.type == "Warning") ? YELLOW : RED});
+ _stream << _linePrefix;
+ _stream << error.type << ": ";
+ }
+ if (error.locationStart >= 0 || error.locationEnd >= 0)
+ {
+ _stream << "(";
+ if (error.locationStart >= 0)
+ _stream << error.locationStart;
+ _stream << "-";
+ if (error.locationEnd >= 0)
+ _stream << error.locationEnd;
+ _stream << "): ";
+ }
+ _stream << error.message << endl;
+ }
+}
+
+string SyntaxTest::errorMessage(Exception const& _e)
+{
+ if (_e.comment() && !_e.comment()->empty())
+ return boost::replace_all_copy(*_e.comment(), "\n", "\\n");
+ else
+ return "NONE";
+}
+
+string SyntaxTest::parseSource(istream& _stream)
+{
+ string source;
+ string line;
+ string const delimiter("// ----");
+ while (getline(_stream, line))
+ if (boost::algorithm::starts_with(line, delimiter))
+ break;
+ else
+ source += line + "\n";
+ return source;
+}
+
+vector<SyntaxTestError> SyntaxTest::parseExpectations(istream& _stream)
+{
+ vector<SyntaxTestError> expectations;
+ string line;
+ while (getline(_stream, line))
+ {
+ auto it = line.begin();
+
+ skipSlashes(it, line.end());
+ skipWhitespace(it, line.end());
+
+ if (it == line.end()) continue;
+
+ auto typeBegin = it;
+ while (it != line.end() && *it != ':')
+ ++it;
+ string errorType(typeBegin, it);
+
+ // skip colon
+ if (it != line.end()) it++;
+
+ skipWhitespace(it, line.end());
+
+ int locationStart = -1;
+ int locationEnd = -1;
+
+ if (it != line.end() && *it == '(')
+ {
+ ++it;
+ locationStart = parseUnsignedInteger(it, line.end());
+ expect(it, line.end(), '-');
+ locationEnd = parseUnsignedInteger(it, line.end());
+ expect(it, line.end(), ')');
+ expect(it, line.end(), ':');
+ }
+
+ skipWhitespace(it, line.end());
+
+ string errorMessage(it, line.end());
+ expectations.emplace_back(SyntaxTestError{
+ move(errorType),
+ move(errorMessage),
+ locationStart,
+ locationEnd
+ });
+ }
+ return expectations;
+}
+
+#if BOOST_VERSION < 105900
+test_case *make_test_case(
+ function<void()> const& _fn,
+ string const& _name,
+ string const& /* _filename */,
+ size_t /* _line */
+)
+{
+ return make_test_case(_fn, _name);
+}
+#endif
+
+bool SyntaxTest::isTestFilename(boost::filesystem::path const& _filename)
+{
+ return _filename.extension().string() == ".sol" &&
+ !boost::starts_with(_filename.string(), "~") &&
+ !boost::starts_with(_filename.string(), ".");
+}
+
+int SyntaxTest::registerTests(
+ boost::unit_test::test_suite& _suite,
+ boost::filesystem::path const& _basepath,
+ boost::filesystem::path const& _path
+)
+{
+ int numTestsAdded = 0;
+ fs::path fullpath = _basepath / _path;
+ if (fs::is_directory(fullpath))
+ {
+ test_suite* sub_suite = BOOST_TEST_SUITE(_path.filename().string());
+ for (auto const& entry: boost::iterator_range<fs::directory_iterator>(
+ fs::directory_iterator(fullpath),
+ fs::directory_iterator()
+ ))
+ if (fs::is_directory(entry.path()) || isTestFilename(entry.path().filename()))
+ numTestsAdded += registerTests(*sub_suite, _basepath, _path / entry.path().filename());
+ _suite.add(sub_suite);
+ }
+ else
+ {
+ static vector<unique_ptr<string>> filenames;
+
+ filenames.emplace_back(new string(_path.string()));
+ _suite.add(make_test_case(
+ [fullpath]
+ {
+ BOOST_REQUIRE_NO_THROW({
+ stringstream errorStream;
+ if (!SyntaxTest(fullpath.string()).run(errorStream))
+ BOOST_ERROR("Test expectation mismatch.\n" + errorStream.str());
+ });
+ },
+ _path.stem().string(),
+ *filenames.back(),
+ 0
+ ));
+ numTestsAdded = 1;
+ }
+ return numTestsAdded;
+}
diff --git a/test/libsolidity/SyntaxTest.h b/test/libsolidity/SyntaxTest.h
new file mode 100644
index 00000000..6159e789
--- /dev/null
+++ b/test/libsolidity/SyntaxTest.h
@@ -0,0 +1,91 @@
+/*
+ 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/>.
+*/
+
+#pragma once
+
+#include <test/libsolidity/AnalysisFramework.h>
+#include <test/libsolidity/FormattedScope.h>
+#include <libsolidity/interface/Exceptions.h>
+
+#include <boost/noncopyable.hpp>
+#include <boost/test/unit_test.hpp>
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+#include <utility>
+
+namespace dev
+{
+namespace solidity
+{
+namespace test
+{
+
+struct SyntaxTestError
+{
+ std::string type;
+ std::string message;
+ int locationStart;
+ int locationEnd;
+ bool operator==(SyntaxTestError const& _rhs) const
+ {
+ return type == _rhs.type &&
+ message == _rhs.message &&
+ locationStart == _rhs.locationStart &&
+ locationEnd == _rhs.locationEnd;
+ }
+};
+
+
+class SyntaxTest: AnalysisFramework
+{
+public:
+ SyntaxTest(std::string const& _filename);
+
+ bool run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false);
+
+ std::vector<SyntaxTestError> const& expectations() const { return m_expectations; }
+ std::string const& source() const { return m_source; }
+ std::vector<SyntaxTestError> const& errorList() const { return m_errorList; }
+
+ static void printErrorList(
+ std::ostream& _stream,
+ std::vector<SyntaxTestError> const& _errors,
+ std::string const& _linePrefix,
+ bool const _formatted = false
+ );
+
+ static int registerTests(
+ boost::unit_test::test_suite& _suite,
+ boost::filesystem::path const& _basepath,
+ boost::filesystem::path const& _path
+ );
+ static bool isTestFilename(boost::filesystem::path const& _filename);
+ static std::string errorMessage(Exception const& _e);
+private:
+ static std::string parseSource(std::istream& _stream);
+ static std::vector<SyntaxTestError> parseExpectations(std::istream& _stream);
+
+ std::string m_source;
+ std::vector<SyntaxTestError> m_expectations;
+ std::vector<SyntaxTestError> m_errorList;
+};
+
+}
+}
+}
diff --git a/test/libsolidity/ViewPureChecker.cpp b/test/libsolidity/ViewPureChecker.cpp
index 26ff461c..cd0a0b01 100644
--- a/test/libsolidity/ViewPureChecker.cpp
+++ b/test/libsolidity/ViewPureChecker.cpp
@@ -20,11 +20,12 @@
#include <test/libsolidity/AnalysisFramework.h>
-#include <test/TestHelper.h>
+#include <test/Options.h>
#include <boost/test/unit_test.hpp>
#include <string>
+#include <tuple>
using namespace std;
@@ -111,6 +112,7 @@ BOOST_AUTO_TEST_CASE(environment_access)
"block.difficulty",
"block.number",
"block.gaslimit",
+ "blockhash(7)",
"gasleft()",
"msg.gas",
"msg.value",
@@ -120,11 +122,12 @@ BOOST_AUTO_TEST_CASE(environment_access)
"this",
"address(1).balance"
};
+ // ``block.blockhash`` and ``blockhash`` are tested seperately below because their usage will
+ // produce warnings that can't be handled in a generic way.
vector<string> pure{
"msg.data",
"msg.data[0]",
"msg.sig",
- "block.blockhash", // Not evaluating the function
"msg",
"block",
"tx"
@@ -132,20 +135,32 @@ BOOST_AUTO_TEST_CASE(environment_access)
for (string const& x: view)
{
CHECK_ERROR(
- "contract C { function f() pure public { var x = " + x + "; x; } }",
+ "contract C { function f() pure public { " + x + "; } }",
TypeError,
"Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires \"view\""
);
}
for (string const& x: pure)
{
- CHECK_WARNING_ALLOW_MULTI(
- "contract C { function f() view public { var x = " + x + "; x; } }",
- (std::vector<std::string>{
- "Function state mutability can be restricted to pure",
- "Use of the \"var\" keyword is deprecated."
- }));
+ CHECK_WARNING(
+ "contract C { function f() view public { " + x + "; } }",
+ "Function state mutability can be restricted to pure"
+ );
}
+
+ CHECK_WARNING_ALLOW_MULTI(
+ "contract C { function f() view public { blockhash; } }",
+ (std::vector<std::string>{
+ "Function state mutability can be restricted to pure",
+ "Statement has no effect."
+ }));
+
+ CHECK_WARNING_ALLOW_MULTI(
+ "contract C { function f() view public { block.blockhash; } }",
+ (std::vector<std::string>{
+ "Function state mutability can be restricted to pure",
+ "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""
+ }));
}
BOOST_AUTO_TEST_CASE(view_error_for_050)
diff --git a/test/libsolidity/syntaxTests/arrayLength/array_length_cannot_be_constant_function_parameter.sol b/test/libsolidity/syntaxTests/arrayLength/array_length_cannot_be_constant_function_parameter.sol
new file mode 100644
index 00000000..11d40f26
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/array_length_cannot_be_constant_function_parameter.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f(uint constant LEN) {
+ uint[LEN] a;
+ }
+}
+// ----
+// TypeError: (62-65): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_function.sol b/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_function.sol
new file mode 100644
index 00000000..92536dd5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_function.sol
@@ -0,0 +1,8 @@
+contract C {
+ uint constant LEN = 10;
+ function f() public pure {
+ uint[LEN] memory a;
+ a;
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_struct.sol b/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_struct.sol
new file mode 100644
index 00000000..89e174f2
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/can_be_constant_in_struct.sol
@@ -0,0 +1,7 @@
+contract C {
+ uint constant LEN = 10;
+ struct Test {
+ uint[LEN] ids;
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/arrayLength/can_be_recursive_constant.sol b/test/libsolidity/syntaxTests/arrayLength/can_be_recursive_constant.sol
new file mode 100644
index 00000000..6810a9d6
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/can_be_recursive_constant.sol
@@ -0,0 +1,6 @@
+contract C {
+ uint constant L = 5;
+ uint constant LEN = L + 4 * L;
+ uint[LEN] ids;
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/arrayLength/cannot_be_function.sol b/test/libsolidity/syntaxTests/arrayLength/cannot_be_function.sol
new file mode 100644
index 00000000..ac3abc4c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/cannot_be_function.sol
@@ -0,0 +1,6 @@
+contract C {
+ function f() {}
+ uint[f] ids;
+}
+// ----
+// TypeError: (42-43): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/cannot_be_function_call.sol b/test/libsolidity/syntaxTests/arrayLength/cannot_be_function_call.sol
new file mode 100644
index 00000000..a6863955
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/cannot_be_function_call.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f(uint x) {}
+ uint constant LEN = f();
+ uint[LEN] ids;
+}
+// ----
+// TypeError: (77-80): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/complex_cyclic_constant.sol b/test/libsolidity/syntaxTests/arrayLength/complex_cyclic_constant.sol
new file mode 100644
index 00000000..254f9f02
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/complex_cyclic_constant.sol
@@ -0,0 +1,10 @@
+contract C {
+ uint constant L2 = LEN - 10;
+ uint constant L1 = L2 / 10;
+ uint constant LEN = 10 + L1 * 5;
+ function f() {
+ uint[LEN] a;
+ }
+}
+// ----
+// TypeError: (36-39): Cyclic constant definition (or maximum recursion depth exhausted).
diff --git a/test/libsolidity/syntaxTests/arrayLength/const_cannot_be_fractional.sol b/test/libsolidity/syntaxTests/arrayLength/const_cannot_be_fractional.sol
new file mode 100644
index 00000000..397bbbcd
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/const_cannot_be_fractional.sol
@@ -0,0 +1,6 @@
+contract C {
+ fixed constant L = 10.5;
+ uint[L] ids;
+}
+// ----
+// TypeError: (51-52): Array with fractional length specified.
diff --git a/test/libsolidity/syntaxTests/arrayLength/constant_var.sol b/test/libsolidity/syntaxTests/arrayLength/constant_var.sol
new file mode 100644
index 00000000..41750250
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/constant_var.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint constant LEN = 10;
+ uint[LEN] ids;
+}
+// ---- \ No newline at end of file
diff --git a/test/libsolidity/syntaxTests/arrayLength/cyclic_constant.sol b/test/libsolidity/syntaxTests/arrayLength/cyclic_constant.sol
new file mode 100644
index 00000000..91ba9045
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/cyclic_constant.sol
@@ -0,0 +1,8 @@
+contract C {
+ uint constant LEN = LEN;
+ function f() {
+ uint[LEN] a;
+ }
+}
+// ----
+// TypeError: (37-40): Cyclic constant definition (or maximum recursion depth exhausted).
diff --git a/test/libsolidity/syntaxTests/arrayLength/inline_array.sol b/test/libsolidity/syntaxTests/arrayLength/inline_array.sol
new file mode 100644
index 00000000..a30745d3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/inline_array.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[[2]] a15;
+}
+// ----
+// TypeError: (22-25): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_1.sol b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_1.sol
new file mode 100644
index 00000000..c92861eb
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_1.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[-true] ids;
+}
+// ----
+// TypeError: (22-27): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_2.sol b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_2.sol
new file mode 100644
index 00000000..92e3c3cf
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_2.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[true/1] ids;
+}
+// ----
+// TypeError: (22-28): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_3.sol b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_3.sol
new file mode 100644
index 00000000..26add45c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_3.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[1/true] ids;
+}
+// ----
+// TypeError: (22-28): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_4.sol b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_4.sol
new file mode 100644
index 00000000..a0d58f4a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_4.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[1.111111E1111111111111] ids;
+}
+// ----
+// TypeError: (22-44): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/invalid_expression_5.sol b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_5.sol
new file mode 100644
index 00000000..38a80867
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/invalid_expression_5.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[3/0] ids;
+}
+// ----
+// TypeError: (22-25): Operator / not compatible with types int_const 3 and int_const 0
diff --git a/test/libsolidity/syntaxTests/arrayLength/non_integer_constant_var.sol b/test/libsolidity/syntaxTests/arrayLength/non_integer_constant_var.sol
new file mode 100644
index 00000000..7a853a34
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/non_integer_constant_var.sol
@@ -0,0 +1,6 @@
+contract C {
+ bool constant LEN = true;
+ uint[LEN] ids;
+}
+// ----
+// TypeError: (52-55): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/not_convertible_to_integer.sol b/test/libsolidity/syntaxTests/arrayLength/not_convertible_to_integer.sol
new file mode 100644
index 00000000..b44ccfe9
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/not_convertible_to_integer.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[true] ids;
+}
+// ----
+// TypeError: (22-26): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/parentheses.sol b/test/libsolidity/syntaxTests/arrayLength/parentheses.sol
new file mode 100644
index 00000000..40f55ad6
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/parentheses.sol
@@ -0,0 +1,25 @@
+contract C {
+ uint constant L1 = (2);
+ uint constant L2 = ((2));
+ uint constant L3 = ((((2))));
+ uint constant L4 = (2 + 1);
+ uint constant L5 = ((2 + 1));
+ uint constant L6 = (((2) + ((1))));
+ uint constant L7 = (2 + 1) / 1;
+ uint constant L8 = (2 + ((1))) / (1);
+ uint[L1] a1;
+ uint[L2] a2;
+ uint[L3] a3;
+ uint[L4] a4;
+ uint[L5] a5;
+ uint[L6] a6;
+ uint[L7] a7;
+ uint[L8] a8;
+ uint[(2)] a9;
+ uint[(2 + 1)] a10;
+ uint[(2 + 1) + 1] a11;
+ uint[((2) + 1) + 1] a12;
+ uint[(2 + 1) + ((1))] a13;
+ uint[(((2) + 1)) + (((1)))] a14;
+ uint[((((2) + 1)) + (((1))))%1] a15;
+}
diff --git a/test/libsolidity/syntaxTests/arrayLength/pure_functions.sol b/test/libsolidity/syntaxTests/arrayLength/pure_functions.sol
new file mode 100644
index 00000000..b620db76
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/pure_functions.sol
@@ -0,0 +1,6 @@
+contract C {
+ uint constant LEN = keccak256(ripemd160(33));
+ uint[LEN] ids;
+}
+// ----
+// TypeError: (72-75): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/too_large.sol b/test/libsolidity/syntaxTests/arrayLength/too_large.sol
new file mode 100644
index 00000000..c90a7494
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/too_large.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[8**90] ids;
+}
+// ----
+// TypeError: (22-27): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/arrayLength/tuples.sol b/test/libsolidity/syntaxTests/arrayLength/tuples.sol
new file mode 100644
index 00000000..bc10b3b5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/arrayLength/tuples.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint[(1,2)] a15;
+}
+// ----
+// TypeError: (22-27): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/constants/addmod_mulmod_rational.sol b/test/libsolidity/syntaxTests/constants/addmod_mulmod_rational.sol
new file mode 100644
index 00000000..26712735
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/addmod_mulmod_rational.sol
@@ -0,0 +1,7 @@
+contract C {
+ uint constant a = addmod(3, 4, 0.1);
+ uint constant b = mulmod(3, 4, 0.1);
+}
+// ----
+// TypeError: (48-51): Invalid type for argument in function call. Invalid implicit conversion from rational_const 1 / 10 to uint256 requested.
+// TypeError: (89-92): Invalid type for argument in function call. Invalid implicit conversion from rational_const 1 / 10 to uint256 requested.
diff --git a/test/libsolidity/syntaxTests/constants/addmod_zero.sol b/test/libsolidity/syntaxTests/constants/addmod_zero.sol
new file mode 100644
index 00000000..18f7d64a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/addmod_zero.sol
@@ -0,0 +1,11 @@
+contract c {
+ uint constant a1 = 0;
+ uint constant a2 = 1;
+ uint constant b1 = addmod(3, 4, 0);
+ uint constant b2 = addmod(3, 4, a1);
+ uint constant b3 = addmod(3, 4, a2 - 1);
+}
+// ----
+// TypeError: (88-103): Arithmetic modulo zero.
+// TypeError: (128-144): Arithmetic modulo zero.
+// TypeError: (169-189): Arithmetic modulo zero.
diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_1.sol b/test/libsolidity/syntaxTests/constants/cyclic_dependency_1.sol
new file mode 100644
index 00000000..cb553fbe
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/cyclic_dependency_1.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint constant a = a;
+}
+// ----
+// TypeError: (17-36): The value of the constant a has a cyclic dependency via a.
diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_2.sol b/test/libsolidity/syntaxTests/constants/cyclic_dependency_2.sol
new file mode 100644
index 00000000..00f9bb0f
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/cyclic_dependency_2.sol
@@ -0,0 +1,10 @@
+contract C {
+ uint constant a = b * c;
+ uint constant b = 7;
+ uint constant c = b + uint(keccak256(d));
+ uint constant d = 2 + a;
+}
+// ----
+// TypeError: (17-40): The value of the constant a has a cyclic dependency via c.
+// TypeError: (71-111): The value of the constant c has a cyclic dependency via d.
+// TypeError: (117-140): The value of the constant d has a cyclic dependency via a.
diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_3.sol b/test/libsolidity/syntaxTests/constants/cyclic_dependency_3.sol
new file mode 100644
index 00000000..969ed50d
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/cyclic_dependency_3.sol
@@ -0,0 +1,11 @@
+contract C {
+ uint constant x = a;
+ uint constant a = b * c;
+ uint constant b = c;
+ uint constant c = b;
+}
+// ----
+// TypeError: (17-36): The value of the constant x has a cyclic dependency via a.
+// TypeError: (42-65): The value of the constant a has a cyclic dependency via b.
+// TypeError: (71-90): The value of the constant b has a cyclic dependency via c.
+// TypeError: (96-115): The value of the constant c has a cyclic dependency via b.
diff --git a/test/libsolidity/syntaxTests/constants/cyclic_dependency_4.sol b/test/libsolidity/syntaxTests/constants/cyclic_dependency_4.sol
new file mode 100644
index 00000000..f01cb98e
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/cyclic_dependency_4.sol
@@ -0,0 +1,6 @@
+contract C {
+ uint constant a = b * c;
+ uint constant b = 7;
+ uint constant c = 4 + uint(keccak256(d));
+ uint constant d = 2 + b;
+} \ No newline at end of file
diff --git a/test/libsolidity/syntaxTests/constants/division_by_zero.sol b/test/libsolidity/syntaxTests/constants/division_by_zero.sol
new file mode 100644
index 00000000..bf6000ec
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/division_by_zero.sol
@@ -0,0 +1,9 @@
+contract c {
+ uint constant a1 = 0;
+ uint constant a2 = 1;
+ uint constant b1 = 7 / a1;
+ uint constant b2 = 7 / (a2 - 1);
+}
+// ----
+// TypeError: (88-94): Division by zero.
+// TypeError: (119-131): Division by zero.
diff --git a/test/libsolidity/syntaxTests/constants/mod_div_rational.sol b/test/libsolidity/syntaxTests/constants/mod_div_rational.sol
new file mode 100644
index 00000000..f8b6ce31
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/mod_div_rational.sol
@@ -0,0 +1,6 @@
+contract C {
+ fixed a1 = 0.1 % -0.4271087646484375;
+ fixed a2 = 0.1 % 0.4271087646484375;
+ fixed a3 = 0 / 0.123;
+ fixed a4 = 0 / -0.123;
+}
diff --git a/test/libsolidity/syntaxTests/constants/mod_zero.sol b/test/libsolidity/syntaxTests/constants/mod_zero.sol
new file mode 100644
index 00000000..f5e4a23a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/mod_zero.sol
@@ -0,0 +1,9 @@
+contract c {
+ uint constant a1 = 0;
+ uint constant a2 = 1;
+ uint constant b1 = 3 % a1;
+ uint constant b2 = 3 % (a2 - 1);
+}
+// ----
+// TypeError: (88-94): Modulo zero.
+// TypeError: (119-131): Modulo zero.
diff --git a/test/libsolidity/syntaxTests/constants/mulmod_zero.sol b/test/libsolidity/syntaxTests/constants/mulmod_zero.sol
new file mode 100644
index 00000000..856d01eb
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/mulmod_zero.sol
@@ -0,0 +1,11 @@
+contract c {
+ uint constant a1 = 0;
+ uint constant a2 = 1;
+ uint constant b1 = mulmod(3, 4, 0);
+ uint constant b2 = mulmod(3, 4, a1);
+ uint constant b3 = mulmod(3, 4, a2 - 1);
+}
+// ----
+// TypeError: (88-103): Arithmetic modulo zero.
+// TypeError: (128-144): Arithmetic modulo zero.
+// TypeError: (169-189): Arithmetic modulo zero.
diff --git a/test/libsolidity/syntaxTests/constants/pure_non_rational.sol b/test/libsolidity/syntaxTests/constants/pure_non_rational.sol
new file mode 100644
index 00000000..4b96f1c7
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constants/pure_non_rational.sol
@@ -0,0 +1,11 @@
+// Tests that the ConstantEvaluator does not crash for pure non-rational functions.
+// Currently it does not evaluate such functions, but this may change in the future
+// causing a division by zero error for a.
+contract C {
+ uint constant a = 1 / (uint(keccak256([0])[0]) - uint(keccak256([0])[0]));
+ uint constant b = 1 / uint(keccak256([0]));
+ uint constant c = uint(keccak256([0]));
+ uint[c] mem;
+}
+// ----
+// TypeError: (392-393): Invalid array length, expected integer literal or constant expression.
diff --git a/test/libsolidity/syntaxTests/constructor_this.sol b/test/libsolidity/syntaxTests/constructor_this.sol
new file mode 100644
index 00000000..9d22a161
--- /dev/null
+++ b/test/libsolidity/syntaxTests/constructor_this.sol
@@ -0,0 +1,12 @@
+contract C {
+ function f() public pure {}
+ constructor() public {
+ C c = this;
+ c.f(); // this does not warn now, but should warn in the future
+ this.f();
+ (this).f();
+ }
+}
+// ----
+// Warning: (172-176): "this" used in constructor. Note that external functions of a contract cannot be called while it is being constructed.
+// Warning: (191-195): "this" used in constructor. Note that external functions of a contract cannot be called while it is being constructed.
diff --git a/test/libsolidity/syntaxTests/docstring_empty_description.sol b/test/libsolidity/syntaxTests/docstring_empty_description.sol
new file mode 100644
index 00000000..0caa1b23
--- /dev/null
+++ b/test/libsolidity/syntaxTests/docstring_empty_description.sol
@@ -0,0 +1,6 @@
+contract C {
+ /// @param id
+ function vote(uint id) public;
+}
+// ----
+// DocstringParsingError: No description given for param id
diff --git a/test/libsolidity/syntaxTests/double_stateVariable_declaration.sol b/test/libsolidity/syntaxTests/double_stateVariable_declaration.sol
new file mode 100644
index 00000000..fda4a17a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/double_stateVariable_declaration.sol
@@ -0,0 +1,6 @@
+contract test {
+ uint256 variable;
+ uint128 variable;
+}
+// ----
+// DeclarationError: (36-52): Identifier already declared.
diff --git a/test/libsolidity/syntaxTests/double_variable_declaration.sol b/test/libsolidity/syntaxTests/double_variable_declaration.sol
new file mode 100644
index 00000000..9ab87959
--- /dev/null
+++ b/test/libsolidity/syntaxTests/double_variable_declaration.sol
@@ -0,0 +1,8 @@
+contract test {
+ function f() pure public {
+ uint256 x;
+ if (true) { uint256 x; }
+ }
+}
+// ----
+// DeclarationError: (71-80): Identifier already declared.
diff --git a/test/libsolidity/syntaxTests/double_variable_declaration_050.sol b/test/libsolidity/syntaxTests/double_variable_declaration_050.sol
new file mode 100644
index 00000000..2f47e6dc
--- /dev/null
+++ b/test/libsolidity/syntaxTests/double_variable_declaration_050.sol
@@ -0,0 +1,11 @@
+pragma experimental "v0.5.0";
+contract test {
+ function f() pure public {
+ uint256 x;
+ if (true) { uint256 x; }
+ }
+}
+// ----
+// Warning: (101-110): This declaration shadows an existing declaration.
+// Warning: (76-85): Unused local variable.
+// Warning: (101-110): Unused local variable.
diff --git a/test/libsolidity/syntaxTests/empty_struct.sol b/test/libsolidity/syntaxTests/empty_struct.sol
new file mode 100644
index 00000000..12655309
--- /dev/null
+++ b/test/libsolidity/syntaxTests/empty_struct.sol
@@ -0,0 +1,5 @@
+contract test {
+ struct A {}
+}
+// ----
+// Warning: (17-28): Defining empty structs is deprecated.
diff --git a/test/libsolidity/syntaxTests/empty_struct_050.sol b/test/libsolidity/syntaxTests/empty_struct_050.sol
new file mode 100644
index 00000000..886f1f83
--- /dev/null
+++ b/test/libsolidity/syntaxTests/empty_struct_050.sol
@@ -0,0 +1,6 @@
+pragma experimental "v0.5.0";
+contract test {
+ struct A {}
+}
+// ----
+// SyntaxError: (47-58): Defining empty structs is disallowed.
diff --git a/test/libsolidity/syntaxTests/functionCalls/arbitrary_parameters_but_restricted_first_type.sol b/test/libsolidity/syntaxTests/functionCalls/arbitrary_parameters_but_restricted_first_type.sol
new file mode 100644
index 00000000..94da5881
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionCalls/arbitrary_parameters_but_restricted_first_type.sol
@@ -0,0 +1,13 @@
+contract C {
+ function f() pure public {
+ abi.encodeWithSelector();
+ abi.encodeWithSignature();
+ abi.encodeWithSelector(uint(2), 2);
+ abi.encodeWithSignature(uint(2), 2);
+ }
+}
+// ----
+// TypeError: (52-76): Need at least 1 arguments for function call, but provided only 0.
+// TypeError: (86-111): Need at least 1 arguments for function call, but provided only 0.
+// TypeError: (144-151): Invalid type for argument in function call. Invalid implicit conversion from uint256 to bytes4 requested.
+// TypeError: (189-196): Invalid type for argument in function call. Invalid implicit conversion from uint256 to string memory requested.
diff --git a/test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol
new file mode 100644
index 00000000..87c3b05b
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/call_value_on_non_payable_function_type.sol
@@ -0,0 +1,8 @@
+contract C {
+ function (uint) external returns (uint) x;
+ function f() public {
+ x.value(2)();
+ }
+}
+// ----
+// TypeError: (94-101): Member "value" not found or not visible after argument-dependent lookup in function (uint256) external returns (uint256) - did you forget the "payable" modifier?
diff --git a/test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol
new file mode 100644
index 00000000..ca2a0196
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/call_value_on_payable_function_type.sol
@@ -0,0 +1,6 @@
+contract C {
+ function (uint) external payable returns (uint) x;
+ function f() public {
+ x.value(2)(1);
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol b/test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol
new file mode 100644
index 00000000..2711dae8
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/delete_external_function_type_invalid.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public {
+ delete this.f;
+ }
+}
+// ----
+// TypeError: (54-60): Expression has to be an lvalue.
diff --git a/test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol
new file mode 100644
index 00000000..a6fe6c22
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/delete_function_type.sol
@@ -0,0 +1,17 @@
+contract C {
+ function(uint) external returns (uint) x;
+ function(uint) internal returns (uint) y;
+ function f() public {
+ delete x;
+ var a = y;
+ delete a;
+ delete y;
+ var c = f;
+ delete c;
+ function(uint) internal returns (uint) g;
+ delete g;
+ }
+}
+// ----
+// Warning: (157-162): Use of the "var" keyword is deprecated.
+// Warning: (212-217): Use of the "var" keyword is deprecated.
diff --git a/test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol b/test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol
new file mode 100644
index 00000000..60da19e4
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/delete_function_type_invalid.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public {
+ delete f;
+ }
+}
+// ----
+// TypeError: (54-55): Expression has to be an lvalue.
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol
new file mode 100644
index 00000000..eb4f0693
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_to_function_type_calldata_parameter.sol
@@ -0,0 +1,10 @@
+// This is a test that checks that the type of the `bytes` parameter is
+// correctly changed from its own type `bytes calldata` to `bytes memory`
+// when converting to a function type.
+contract C {
+ function f(function(bytes memory) pure external /*g*/) pure public { }
+ function callback(bytes) pure external {}
+ function g() view public {
+ f(this.callback);
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_public_variable.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_public_variable.sol
new file mode 100644
index 00000000..0a6d1e53
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_public_variable.sol
@@ -0,0 +1,11 @@
+contract C {
+ function (uint) external public x;
+
+ function g(uint) public {
+ x = this.g;
+ }
+ function f() public view returns (function(uint) external) {
+ return this.x();
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol
new file mode 100644
index 00000000..8b14d3dc
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_returning_internal.sol
@@ -0,0 +1,5 @@
+contract C {
+ function() external returns (function () internal) x;
+}
+// ----
+// TypeError: (46-67): Internal type cannot be used for external function type.
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol
new file mode 100644
index 00000000..3e264c8c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_taking_internal.sol
@@ -0,0 +1,5 @@
+contract C {
+ function(function () internal) external x;
+}
+// ----
+// TypeError: (26-47): Internal type cannot be used for external function type.
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol
new file mode 100644
index 00000000..b86425db
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_address.sol
@@ -0,0 +1,5 @@
+contract C {
+ function f() public view returns (address) {
+ return address(this.f);
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol
new file mode 100644
index 00000000..f4287223
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/external_function_type_to_uint.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public returns (uint) {
+ return uint(this.f);
+ }
+}
+// ----
+// TypeError: (69-81): Explicit type conversion not allowed from "function () external returns (uint256)" to "uint256".
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type.sol b/test/libsolidity/syntaxTests/functionTypes/function_type.sol
new file mode 100644
index 00000000..23d50136
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type.sol
@@ -0,0 +1,6 @@
+contract C {
+ function f() pure public {
+ function(uint) returns (uint) x;
+ x;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol
new file mode 100644
index 00000000..ec23d637
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_arrays.sol
@@ -0,0 +1,11 @@
+contract C {
+ function(uint) external returns (uint)[] public x;
+ function(uint) internal returns (uint)[10] y;
+ function f() view public {
+ function(uint) returns (uint)[10] memory a;
+ function(uint) returns (uint)[10] storage b = y;
+ function(uint) external returns (uint)[] memory c;
+ c = new function(uint) external returns (uint)[](200);
+ a; b;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol
new file mode 100644
index 00000000..95ebc179
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor.sol
@@ -0,0 +1,7 @@
+contract C {
+ // Fool parser into parsing a constructor as a function type.
+ constructor() x;
+}
+// ----
+// Warning: (83-99): Modifiers of functions without implementation are ignored.
+// DeclarationError: (97-98): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol
new file mode 100644
index 00000000..b7763d28
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_constructor_local.sol
@@ -0,0 +1,8 @@
+contract C {
+ // Fool parser into parsing a constructor as a function type.
+ function f() {
+ constructor() x;
+ }
+}
+// ----
+// ParserError: (118-118): Expected token Semicolon got 'Identifier'
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_internal_public_variable.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_internal_public_variable.sol
new file mode 100644
index 00000000..4eb53227
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_internal_public_variable.sol
@@ -0,0 +1,5 @@
+contract C {
+ function(bytes memory) internal public a;
+}
+// ----
+// TypeError: (17-57): Internal or recursive type is not allowed for public state variables.
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol
new file mode 100644
index 00000000..da66ec8a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_parameter.sol
@@ -0,0 +1,7 @@
+contract C {
+ uint x;
+ function f(function(uint) external returns (uint) g) public returns (function(uint) external returns (uint)) {
+ x = 2;
+ return g;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol
new file mode 100644
index 00000000..9cd313c8
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_returned.sol
@@ -0,0 +1,5 @@
+contract C {
+ function f() public pure returns (function(uint) pure external returns (uint) g) {
+ return g;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol
new file mode 100644
index 00000000..f0240472
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_type_variable_external_internal.sol
@@ -0,0 +1,6 @@
+contract test {
+ function fa(bytes memory) public { }
+ function(bytes memory) external internal a = fa;
+}
+// ----
+// TypeError: (106-108): Type function (bytes memory) is not implicitly convertible to expected type function (bytes memory) external.
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_types_internal_visibility_error.sol b/test/libsolidity/syntaxTests/functionTypes/function_types_internal_visibility_error.sol
new file mode 100644
index 00000000..36206d63
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_types_internal_visibility_error.sol
@@ -0,0 +1,7 @@
+contract C {
+ // This is an error, you should explicitly use
+ // `external public` to fix it - `internal public` does not exist.
+ function(bytes memory) public a;
+}
+// ----
+// TypeError: (139-170): Invalid visibility, can only be "external" or "internal".
diff --git a/test/libsolidity/syntaxTests/functionTypes/function_types_variable_visibility.sol b/test/libsolidity/syntaxTests/functionTypes/function_types_variable_visibility.sol
new file mode 100644
index 00000000..91c2420a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/function_types_variable_visibility.sol
@@ -0,0 +1,9 @@
+contract C {
+ function(bytes memory) a1;
+ function(bytes memory) internal b1;
+ function(bytes memory) internal internal b2;
+ function(bytes memory) external c1;
+ function(bytes memory) external internal c2;
+ function(bytes memory) external public c3;
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol
new file mode 100644
index 00000000..fa92d559
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter.sol
@@ -0,0 +1,8 @@
+// It should not be possible to give internal functions
+// as parameters to external functions.
+contract C {
+ function f(function(uint) internal returns (uint) x) public {
+ }
+}
+// ----
+// TypeError: (124-164): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol
new file mode 100644
index 00000000..b37fb285
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_external.sol
@@ -0,0 +1,6 @@
+library L {
+ function f(function(uint) internal returns (uint) x) public {
+ }
+}
+// ----
+// TypeError: (27-67): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol
new file mode 100644
index 00000000..7ffa447e
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_as_external_parameter_in_library_internal.sol
@@ -0,0 +1,4 @@
+library L {
+ function f(function(uint) internal returns (uint) /*x*/) pure internal {
+ }
+}
diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol
new file mode 100644
index 00000000..41fcd0a4
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_returned_from_public_function.sol
@@ -0,0 +1,7 @@
+// It should not be possible to return internal functions from external functions.
+contract C {
+ function f() public returns (function(uint) internal returns (uint) x) {
+ }
+}
+// ----
+// TypeError: (129-169): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol b/test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol
new file mode 100644
index 00000000..b75a0d43
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/internal_function_type_to_address.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public returns (address) {
+ return address(f);
+ }
+}
+// ----
+// TypeError: (72-82): Explicit type conversion not allowed from "function () returns (address)" to "address".
diff --git a/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol
new file mode 100644
index 00000000..a7cb9d92
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type.sol
@@ -0,0 +1,5 @@
+contract C {
+ function (uint) internal payable returns (uint) x;
+}
+// ----
+// TypeError: (17-66): Only external function types can be payable.
diff --git a/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol
new file mode 100644
index 00000000..5c6dc056
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/payable_internal_function_type_is_not_fatal.sol
@@ -0,0 +1,9 @@
+contract C {
+ function (uint) internal payable returns (uint) x;
+
+ function g() public {
+ x = g;
+ }
+}
+// ----
+// TypeError: (17-66): Only external function types can be payable.
diff --git a/test/libsolidity/syntaxTests/functionTypes/private_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/private_function_type.sol
new file mode 100644
index 00000000..9d4f0a09
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/private_function_type.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public {
+ function(uint) private returns (uint) x;
+ }
+}
+// ----
+// TypeError: (47-86): Invalid visibility, can only be "external" or "internal".
diff --git a/test/libsolidity/syntaxTests/functionTypes/public_function_type.sol b/test/libsolidity/syntaxTests/functionTypes/public_function_type.sol
new file mode 100644
index 00000000..756766d3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/public_function_type.sol
@@ -0,0 +1,7 @@
+contract C {
+ function f() public {
+ function(uint) public returns (uint) x;
+ }
+}
+// ----
+// TypeError: (47-85): Invalid visibility, can only be "external" or "internal".
diff --git a/test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol b/test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol
new file mode 100644
index 00000000..10c6767c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/valid_function_type_variables.sol
@@ -0,0 +1,23 @@
+contract test {
+ function fa(uint) {}
+ function fb(uint) internal {}
+ function fc(uint) internal {}
+ function fd(uint) external {}
+ function fe(uint) external {}
+ function ff(uint) internal {}
+ function fg(uint) internal pure {}
+ function fh(uint) pure internal {}
+
+ function(uint) a = fa;
+ function(uint) internal b = fb; // (explicit internal applies to the function type)
+ function(uint) internal internal c = fc;
+ function(uint) external d = this.fd;
+ function(uint) external internal e = this.fe;
+ function(uint) internal public f = ff;
+ function(uint) internal pure public g = fg;
+ function(uint) pure internal public h = fh;
+}
+// ----
+// TypeError: (545-582): Internal or recursive type is not allowed for public state variables.
+// TypeError: (588-630): Internal or recursive type is not allowed for public state variables.
+// TypeError: (636-678): Internal or recursive type is not allowed for public state variables.
diff --git a/test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol
new file mode 100644
index 00000000..072c7eb7
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_parameters_with_names.sol
@@ -0,0 +1,5 @@
+contract C {
+ function(uint a) f;
+}
+// ----
+// Warning: (26-32): Naming function type parameters is deprecated.
diff --git a/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol
new file mode 100644
index 00000000..67a74e54
--- /dev/null
+++ b/test/libsolidity/syntaxTests/functionTypes/warn_function_type_return_parameters_with_names.sol
@@ -0,0 +1,5 @@
+contract C {
+ function(uint) returns (bool ret) f;
+}
+// ----
+// Warning: (41-49): Naming function type return parameters is deprecated.
diff --git a/test/libsolidity/syntaxTests/inheritance/allow_empty_duplicated_super_constructor_call.sol b/test/libsolidity/syntaxTests/inheritance/allow_empty_duplicated_super_constructor_call.sol
new file mode 100644
index 00000000..ce9d5f5f
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/allow_empty_duplicated_super_constructor_call.sol
@@ -0,0 +1,2 @@
+contract A { constructor() public { } }
+contract B is A { constructor() A() public { } }
diff --git a/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses.sol b/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses.sol
new file mode 100644
index 00000000..0b18b995
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses.sol
@@ -0,0 +1,7 @@
+contract Base {
+ constructor(uint) public {}
+}
+contract Derived is Base(2) { }
+contract Derived2 is Base(), Derived() { }
+// ----
+// Warning: (101-107): Wrong argument count for constructor call: 0 arguments given but expected 1.
diff --git a/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses_V050.sol b/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses_V050.sol
new file mode 100644
index 00000000..db04ab8c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses_V050.sol
@@ -0,0 +1,9 @@
+pragma experimental "v0.5.0";
+
+contract Base {
+ constructor(uint) public {}
+}
+contract Derived is Base(2) { }
+contract Derived2 is Base(), Derived() { }
+// ----
+// TypeError: (132-138): Wrong argument count for constructor call: 0 arguments given but expected 1.
diff --git a/test/libsolidity/syntaxTests/inheritance/base_arguments_multiple_inheritance.sol b/test/libsolidity/syntaxTests/inheritance/base_arguments_multiple_inheritance.sol
new file mode 100644
index 00000000..015b33e5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/base_arguments_multiple_inheritance.sol
@@ -0,0 +1,9 @@
+contract Base {
+ constructor(uint) public { }
+}
+contract Base1 is Base(3) {}
+contract Derived is Base, Base1 {
+ constructor(uint i) Base(i) public {}
+}
+// ----
+// Warning: (138-145): Base constructor arguments given twice.
diff --git a/test/libsolidity/syntaxTests/inheritance/base_arguments_no_parentheses.sol b/test/libsolidity/syntaxTests/inheritance/base_arguments_no_parentheses.sol
new file mode 100644
index 00000000..24cca8f0
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/base_arguments_no_parentheses.sol
@@ -0,0 +1,5 @@
+contract Base {
+ constructor(uint) public {}
+}
+contract Derived is Base(2) { }
+contract Derived2 is Base, Derived {}
diff --git a/test/libsolidity/syntaxTests/inheritance/disallow_modifier_style_without_parentheses.sol b/test/libsolidity/syntaxTests/inheritance/disallow_modifier_style_without_parentheses.sol
new file mode 100644
index 00000000..6cf68d2a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/disallow_modifier_style_without_parentheses.sol
@@ -0,0 +1,4 @@
+contract A { constructor() public { } }
+contract B is A { constructor() A public { } }
+// ----
+// Warning: (72-73): Modifier-style base constructor call without arguments.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/ancestor.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/ancestor.sol
new file mode 100644
index 00000000..24cff54d
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/ancestor.sol
@@ -0,0 +1,5 @@
+contract A { constructor(uint) public { } }
+contract B is A(2) { constructor() public { } }
+contract C is B { constructor() A(3) public { } }
+// ----
+// Warning: (125-129): Base constructor arguments given twice.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/ancestor_V050.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/ancestor_V050.sol
new file mode 100644
index 00000000..8d5df5bf
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/ancestor_V050.sol
@@ -0,0 +1,7 @@
+pragma experimental "v0.5.0";
+
+contract A { constructor(uint) public { } }
+contract B is A(2) { constructor() public { } }
+contract C is B { constructor() A(3) public { } }
+// ----
+// DeclarationError: (156-160): Base constructor arguments given twice.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base.sol
new file mode 100644
index 00000000..9ceaea5e
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base.sol
@@ -0,0 +1,4 @@
+contract A { constructor(uint) public { } }
+contract B is A(2) { constructor() A(3) public { } }
+// ----
+// Warning: (79-83): Base constructor arguments given twice.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_V050.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_V050.sol
new file mode 100644
index 00000000..f9325f99
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_V050.sol
@@ -0,0 +1,6 @@
+pragma experimental "v0.5.0";
+
+contract A { constructor(uint) public { } }
+contract B is A(2) { constructor() A(3) public { } }
+// ----
+// DeclarationError: (110-114): Base constructor arguments given twice.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi.sol
new file mode 100644
index 00000000..e5c2aa36
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi.sol
@@ -0,0 +1,7 @@
+contract C { constructor(uint) public {} }
+contract A is C(2) {}
+contract B is C(2) {}
+contract D is A, B { constructor() C(3) public {} }
+// ----
+// Warning: (122-126): Base constructor arguments given twice.
+// Warning: (122-126): Base constructor arguments given twice.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor.sol
new file mode 100644
index 00000000..1abf2992
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor.sol
@@ -0,0 +1,6 @@
+contract C { constructor(uint) public {} }
+contract A is C(2) {}
+contract B is C(2) {}
+contract D is A, B {}
+// ----
+// Warning: (87-108): Base constructor arguments given twice.
diff --git a/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor_modifier_style.sol b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor_modifier_style.sol
new file mode 100644
index 00000000..e15242db
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/duplicated_constructor_call/base_multi_no_constructor_modifier_style.sol
@@ -0,0 +1,6 @@
+contract C { constructor(uint) public {} }
+contract A is C { constructor() C(2) public {} }
+contract B is C { constructor() C(2) public {} }
+contract D is A, B { }
+// ----
+// Warning: (141-163): Base constructor arguments given twice.
diff --git a/test/libsolidity/syntaxTests/inheritance/too_few_base_arguments.sol b/test/libsolidity/syntaxTests/inheritance/too_few_base_arguments.sol
new file mode 100644
index 00000000..c55c41f2
--- /dev/null
+++ b/test/libsolidity/syntaxTests/inheritance/too_few_base_arguments.sol
@@ -0,0 +1,10 @@
+contract Base {
+ constructor(uint, uint) public {}
+}
+contract Derived is Base(2) { }
+contract Derived2 is Base {
+ constructor() Base(2) public { }
+}
+// ----
+// TypeError: (74-81): Wrong argument count for constructor call: 1 arguments given but expected 2.
+// TypeError: (130-137): Wrong argument count for modifier invocation: 1 arguments given but expected 2.
diff --git a/test/libsolidity/syntaxTests/literalOperations/division_by_zero.sol b/test/libsolidity/syntaxTests/literalOperations/division_by_zero.sol
new file mode 100644
index 00000000..b52b4c51
--- /dev/null
+++ b/test/libsolidity/syntaxTests/literalOperations/division_by_zero.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint constant a = 1 / 0;
+}
+// ----
+// TypeError: (35-40): Operator / not compatible with types int_const 1 and int_const 0
diff --git a/test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex.sol b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex.sol
new file mode 100644
index 00000000..8cc3b6f2
--- /dev/null
+++ b/test/libsolidity/syntaxTests/literalOperations/division_by_zero_complex.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint constant a = 1 / ((1+3)-4);
+}
+// ----
+// TypeError: (35-48): Operator / not compatible with types int_const 1 and int_const 0
diff --git a/test/libsolidity/syntaxTests/literalOperations/mod_zero.sol b/test/libsolidity/syntaxTests/literalOperations/mod_zero.sol
new file mode 100644
index 00000000..1bbbc3fc
--- /dev/null
+++ b/test/libsolidity/syntaxTests/literalOperations/mod_zero.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint constant b3 = 1 % 0;
+}
+// ----
+// TypeError: (36-41): Operator % not compatible with types int_const 1 and int_const 0
diff --git a/test/libsolidity/syntaxTests/literalOperations/mod_zero_complex.sol b/test/libsolidity/syntaxTests/literalOperations/mod_zero_complex.sol
new file mode 100644
index 00000000..4899cac3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/literalOperations/mod_zero_complex.sol
@@ -0,0 +1,5 @@
+contract C {
+ uint constant b3 = 1 % (-4+((2)*2));
+}
+// ----
+// TypeError: (36-52): Operator % not compatible with types int_const 1 and int_const 0
diff --git a/test/libsolidity/syntaxTests/literal_comparisons.sol b/test/libsolidity/syntaxTests/literal_comparisons.sol
new file mode 100644
index 00000000..dd2afcaa
--- /dev/null
+++ b/test/libsolidity/syntaxTests/literal_comparisons.sol
@@ -0,0 +1,7 @@
+contract test {
+ function f(int8 x) public pure {
+ if (x == 1) {}
+ if (1 == x) {}
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/modifiers/base_constructor_double_invocation.sol b/test/libsolidity/syntaxTests/modifiers/base_constructor_double_invocation.sol
new file mode 100644
index 00000000..bdbab5d8
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/base_constructor_double_invocation.sol
@@ -0,0 +1,7 @@
+contract C { constructor(uint a) public {} }
+contract B is C {
+ constructor() C(2) C(2) public {}
+}
+// ----
+// Warning: (81-85): Base constructor arguments given twice.
+// DeclarationError: (86-90): Base constructor already provided.
diff --git a/test/libsolidity/syntaxTests/modifiers/constructor_call_invalid_arg_count.sol b/test/libsolidity/syntaxTests/modifiers/constructor_call_invalid_arg_count.sol
new file mode 100644
index 00000000..4a2b5c4a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/constructor_call_invalid_arg_count.sol
@@ -0,0 +1,9 @@
+// This caused a segfault in an earlier version
+contract C {
+ constructor() public {}
+}
+contract D is C {
+ constructor() C(5) public {}
+}
+// ----
+// TypeError: (127-131): Wrong argument count for modifier invocation: 1 arguments given but expected 0.
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_double_invocation.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_double_invocation.sol
new file mode 100644
index 00000000..75624192
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_double_invocation.sol
@@ -0,0 +1,4 @@
+contract B {
+ function f(uint x) mod(x) mod(2) public pure { }
+ modifier mod(uint a) { if (a > 0) _; }
+}
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation.sol
new file mode 100644
index 00000000..e15fcf49
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation.sol
@@ -0,0 +1,5 @@
+contract B {
+ function f() mod1(2, true) mod2("0123456") pure public { }
+ modifier mod1(uint a, bool b) { if (b) _; }
+ modifier mod2(bytes7 a) { while (a == "1234567") _; }
+}
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol
new file mode 100644
index 00000000..00031924
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables.sol
@@ -0,0 +1,4 @@
+contract B {
+ function f() mod(x) pure public { uint x = 7; }
+ modifier mod(uint a) { if (a > 0) _; }
+}
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol
new file mode 100644
index 00000000..c19ccf2c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_local_variables050.sol
@@ -0,0 +1,7 @@
+pragma experimental "v0.5.0";
+contract B {
+ function f() mod(x) pure public { uint x = 7; }
+ modifier mod(uint a) { if (a > 0) _; }
+}
+// ----
+// DeclarationError: (64-65): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_parameters.sol b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_parameters.sol
new file mode 100644
index 00000000..de2a8f48
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_modifier_invocation_parameters.sol
@@ -0,0 +1,5 @@
+contract B {
+ function f(uint8 a) mod1(a, true) mod2(r) pure public returns (bytes7 r) { }
+ modifier mod1(uint a, bool b) { if (b) _; }
+ modifier mod2(bytes7 a) { while (a == "1234567") _; }
+}
diff --git a/test/libsolidity/syntaxTests/modifiers/function_overrides_modifier.sol b/test/libsolidity/syntaxTests/modifiers/function_overrides_modifier.sol
new file mode 100644
index 00000000..a64c2790
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/function_overrides_modifier.sol
@@ -0,0 +1,5 @@
+contract A { function mod(uint a) public { } }
+contract B is A { modifier mod(uint a) { _; } }
+// ----
+// DeclarationError: (65-92): Identifier already declared.
+// TypeError: (65-92): Override changes function to modifier.
diff --git a/test/libsolidity/syntaxTests/modifiers/illegal_modifier_override.sol b/test/libsolidity/syntaxTests/modifiers/illegal_modifier_override.sol
new file mode 100644
index 00000000..958be686
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/illegal_modifier_override.sol
@@ -0,0 +1,4 @@
+contract A { modifier mod(uint a) { _; } }
+contract B is A { modifier mod(uint8 a) { _; } }
+// ----
+// TypeError: (61-89): Override changes modifier signature.
diff --git a/test/libsolidity/syntaxTests/modifiers/invalid_function_modifier_type.sol b/test/libsolidity/syntaxTests/modifiers/invalid_function_modifier_type.sol
new file mode 100644
index 00000000..c1e3108b
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/invalid_function_modifier_type.sol
@@ -0,0 +1,6 @@
+contract B {
+ function f() mod1(true) public { }
+ modifier mod1(uint a) { if (a > 0) _; }
+}
+// ----
+// TypeError: (35-39): Invalid type for argument in modifier invocation. Invalid implicit conversion from bool to uint256 requested.
diff --git a/test/libsolidity/syntaxTests/modifiers/legal_modifier_override.sol b/test/libsolidity/syntaxTests/modifiers/legal_modifier_override.sol
new file mode 100644
index 00000000..51c3fd80
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/legal_modifier_override.sol
@@ -0,0 +1,2 @@
+contract A { modifier mod(uint a) { _; } }
+contract B is A { modifier mod(uint a) { _; } }
diff --git a/test/libsolidity/syntaxTests/modifiers/modifier_overrides_function.sol b/test/libsolidity/syntaxTests/modifiers/modifier_overrides_function.sol
new file mode 100644
index 00000000..a43646c3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/modifier_overrides_function.sol
@@ -0,0 +1,5 @@
+contract A { modifier mod(uint a) { _; } }
+contract B is A { function mod(uint a) public { } }
+// ----
+// DeclarationError: (61-92): Identifier already declared.
+// TypeError: (13-40): Override changes modifier to function.
diff --git a/test/libsolidity/syntaxTests/modifiers/modifier_returns_value.sol b/test/libsolidity/syntaxTests/modifiers/modifier_returns_value.sol
new file mode 100644
index 00000000..d22e836c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/modifier_returns_value.sol
@@ -0,0 +1,6 @@
+contract A {
+ function f(uint a) mod(2) public returns (uint r) { }
+ modifier mod(uint a) { _; return 7; }
+}
+// ----
+// TypeError: (101-109): Return arguments not allowed.
diff --git a/test/libsolidity/syntaxTests/modifiers/modifier_without_underscore.sol b/test/libsolidity/syntaxTests/modifiers/modifier_without_underscore.sol
new file mode 100644
index 00000000..6198d3c5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/modifier_without_underscore.sol
@@ -0,0 +1,5 @@
+contract test {
+ modifier m() {}
+}
+// ----
+// SyntaxError: (33-35): Modifier body does not contain '_'.
diff --git a/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_050.sol b/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_050.sol
new file mode 100644
index 00000000..af1babbc
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_050.sol
@@ -0,0 +1,10 @@
+pragma experimental "v0.5.0";
+contract C
+{
+ modifier only_owner() { _; }
+ function foo() only_owner public;
+ function bar() public only_owner;
+}
+// ----
+// SyntaxError: (80-113): Functions without implementation cannot have modifiers.
+// SyntaxError: (118-151): Functions without implementation cannot have modifiers.
diff --git a/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_no_parser_error.sol b/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_no_parser_error.sol
new file mode 100644
index 00000000..e18c5cf9
--- /dev/null
+++ b/test/libsolidity/syntaxTests/modifiers/modifiers_on_abstract_functions_no_parser_error.sol
@@ -0,0 +1,13 @@
+// Previous versions of Solidity turned this
+// into a parser error (they wrongly recognized
+// these functions as state variables of
+// function type).
+contract C
+{
+ modifier only_owner() { _; }
+ function foo() only_owner public;
+ function bar() public only_owner;
+}
+// ----
+// Warning: (203-236): Modifiers of functions without implementation are ignored.
+// Warning: (241-274): Modifiers of functions without implementation are ignored.
diff --git a/test/libsolidity/syntaxTests/more_than_256_declarationerrors.sol b/test/libsolidity/syntaxTests/more_than_256_declarationerrors.sol
new file mode 100644
index 00000000..2d75f29b
--- /dev/null
+++ b/test/libsolidity/syntaxTests/more_than_256_declarationerrors.sol
@@ -0,0 +1,524 @@
+contract C {
+ function f() {
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ b = 5;
+ }
+}
+// ----
+// DeclarationError: (34-35): Undeclared identifier.
+// DeclarationError: (45-46): Undeclared identifier.
+// DeclarationError: (56-57): Undeclared identifier.
+// DeclarationError: (67-68): Undeclared identifier.
+// DeclarationError: (78-79): Undeclared identifier.
+// DeclarationError: (89-90): Undeclared identifier.
+// DeclarationError: (100-101): Undeclared identifier.
+// DeclarationError: (111-112): Undeclared identifier.
+// DeclarationError: (122-123): Undeclared identifier.
+// DeclarationError: (133-134): Undeclared identifier.
+// DeclarationError: (144-145): Undeclared identifier.
+// DeclarationError: (155-156): Undeclared identifier.
+// DeclarationError: (166-167): Undeclared identifier.
+// DeclarationError: (177-178): Undeclared identifier.
+// DeclarationError: (188-189): Undeclared identifier.
+// DeclarationError: (199-200): Undeclared identifier.
+// DeclarationError: (210-211): Undeclared identifier.
+// DeclarationError: (221-222): Undeclared identifier.
+// DeclarationError: (232-233): Undeclared identifier.
+// DeclarationError: (243-244): Undeclared identifier.
+// DeclarationError: (254-255): Undeclared identifier.
+// DeclarationError: (265-266): Undeclared identifier.
+// DeclarationError: (276-277): Undeclared identifier.
+// DeclarationError: (287-288): Undeclared identifier.
+// DeclarationError: (298-299): Undeclared identifier.
+// DeclarationError: (309-310): Undeclared identifier.
+// DeclarationError: (320-321): Undeclared identifier.
+// DeclarationError: (331-332): Undeclared identifier.
+// DeclarationError: (342-343): Undeclared identifier.
+// DeclarationError: (353-354): Undeclared identifier.
+// DeclarationError: (364-365): Undeclared identifier.
+// DeclarationError: (375-376): Undeclared identifier.
+// DeclarationError: (386-387): Undeclared identifier.
+// DeclarationError: (397-398): Undeclared identifier.
+// DeclarationError: (408-409): Undeclared identifier.
+// DeclarationError: (419-420): Undeclared identifier.
+// DeclarationError: (430-431): Undeclared identifier.
+// DeclarationError: (441-442): Undeclared identifier.
+// DeclarationError: (452-453): Undeclared identifier.
+// DeclarationError: (463-464): Undeclared identifier.
+// DeclarationError: (474-475): Undeclared identifier.
+// DeclarationError: (485-486): Undeclared identifier.
+// DeclarationError: (496-497): Undeclared identifier.
+// DeclarationError: (507-508): Undeclared identifier.
+// DeclarationError: (518-519): Undeclared identifier.
+// DeclarationError: (529-530): Undeclared identifier.
+// DeclarationError: (540-541): Undeclared identifier.
+// DeclarationError: (551-552): Undeclared identifier.
+// DeclarationError: (562-563): Undeclared identifier.
+// DeclarationError: (573-574): Undeclared identifier.
+// DeclarationError: (584-585): Undeclared identifier.
+// DeclarationError: (595-596): Undeclared identifier.
+// DeclarationError: (606-607): Undeclared identifier.
+// DeclarationError: (617-618): Undeclared identifier.
+// DeclarationError: (628-629): Undeclared identifier.
+// DeclarationError: (639-640): Undeclared identifier.
+// DeclarationError: (650-651): Undeclared identifier.
+// DeclarationError: (661-662): Undeclared identifier.
+// DeclarationError: (672-673): Undeclared identifier.
+// DeclarationError: (683-684): Undeclared identifier.
+// DeclarationError: (694-695): Undeclared identifier.
+// DeclarationError: (705-706): Undeclared identifier.
+// DeclarationError: (716-717): Undeclared identifier.
+// DeclarationError: (727-728): Undeclared identifier.
+// DeclarationError: (738-739): Undeclared identifier.
+// DeclarationError: (749-750): Undeclared identifier.
+// DeclarationError: (760-761): Undeclared identifier.
+// DeclarationError: (771-772): Undeclared identifier.
+// DeclarationError: (782-783): Undeclared identifier.
+// DeclarationError: (793-794): Undeclared identifier.
+// DeclarationError: (804-805): Undeclared identifier.
+// DeclarationError: (815-816): Undeclared identifier.
+// DeclarationError: (826-827): Undeclared identifier.
+// DeclarationError: (837-838): Undeclared identifier.
+// DeclarationError: (848-849): Undeclared identifier.
+// DeclarationError: (859-860): Undeclared identifier.
+// DeclarationError: (870-871): Undeclared identifier.
+// DeclarationError: (881-882): Undeclared identifier.
+// DeclarationError: (892-893): Undeclared identifier.
+// DeclarationError: (903-904): Undeclared identifier.
+// DeclarationError: (914-915): Undeclared identifier.
+// DeclarationError: (925-926): Undeclared identifier.
+// DeclarationError: (936-937): Undeclared identifier.
+// DeclarationError: (947-948): Undeclared identifier.
+// DeclarationError: (958-959): Undeclared identifier.
+// DeclarationError: (969-970): Undeclared identifier.
+// DeclarationError: (980-981): Undeclared identifier.
+// DeclarationError: (991-992): Undeclared identifier.
+// DeclarationError: (1002-1003): Undeclared identifier.
+// DeclarationError: (1013-1014): Undeclared identifier.
+// DeclarationError: (1024-1025): Undeclared identifier.
+// DeclarationError: (1035-1036): Undeclared identifier.
+// DeclarationError: (1046-1047): Undeclared identifier.
+// DeclarationError: (1057-1058): Undeclared identifier.
+// DeclarationError: (1068-1069): Undeclared identifier.
+// DeclarationError: (1079-1080): Undeclared identifier.
+// DeclarationError: (1090-1091): Undeclared identifier.
+// DeclarationError: (1101-1102): Undeclared identifier.
+// DeclarationError: (1112-1113): Undeclared identifier.
+// DeclarationError: (1123-1124): Undeclared identifier.
+// DeclarationError: (1134-1135): Undeclared identifier.
+// DeclarationError: (1145-1146): Undeclared identifier.
+// DeclarationError: (1156-1157): Undeclared identifier.
+// DeclarationError: (1167-1168): Undeclared identifier.
+// DeclarationError: (1178-1179): Undeclared identifier.
+// DeclarationError: (1189-1190): Undeclared identifier.
+// DeclarationError: (1200-1201): Undeclared identifier.
+// DeclarationError: (1211-1212): Undeclared identifier.
+// DeclarationError: (1222-1223): Undeclared identifier.
+// DeclarationError: (1233-1234): Undeclared identifier.
+// DeclarationError: (1244-1245): Undeclared identifier.
+// DeclarationError: (1255-1256): Undeclared identifier.
+// DeclarationError: (1266-1267): Undeclared identifier.
+// DeclarationError: (1277-1278): Undeclared identifier.
+// DeclarationError: (1288-1289): Undeclared identifier.
+// DeclarationError: (1299-1300): Undeclared identifier.
+// DeclarationError: (1310-1311): Undeclared identifier.
+// DeclarationError: (1321-1322): Undeclared identifier.
+// DeclarationError: (1332-1333): Undeclared identifier.
+// DeclarationError: (1343-1344): Undeclared identifier.
+// DeclarationError: (1354-1355): Undeclared identifier.
+// DeclarationError: (1365-1366): Undeclared identifier.
+// DeclarationError: (1376-1377): Undeclared identifier.
+// DeclarationError: (1387-1388): Undeclared identifier.
+// DeclarationError: (1398-1399): Undeclared identifier.
+// DeclarationError: (1409-1410): Undeclared identifier.
+// DeclarationError: (1420-1421): Undeclared identifier.
+// DeclarationError: (1431-1432): Undeclared identifier.
+// DeclarationError: (1442-1443): Undeclared identifier.
+// DeclarationError: (1453-1454): Undeclared identifier.
+// DeclarationError: (1464-1465): Undeclared identifier.
+// DeclarationError: (1475-1476): Undeclared identifier.
+// DeclarationError: (1486-1487): Undeclared identifier.
+// DeclarationError: (1497-1498): Undeclared identifier.
+// DeclarationError: (1508-1509): Undeclared identifier.
+// DeclarationError: (1519-1520): Undeclared identifier.
+// DeclarationError: (1530-1531): Undeclared identifier.
+// DeclarationError: (1541-1542): Undeclared identifier.
+// DeclarationError: (1552-1553): Undeclared identifier.
+// DeclarationError: (1563-1564): Undeclared identifier.
+// DeclarationError: (1574-1575): Undeclared identifier.
+// DeclarationError: (1585-1586): Undeclared identifier.
+// DeclarationError: (1596-1597): Undeclared identifier.
+// DeclarationError: (1607-1608): Undeclared identifier.
+// DeclarationError: (1618-1619): Undeclared identifier.
+// DeclarationError: (1629-1630): Undeclared identifier.
+// DeclarationError: (1640-1641): Undeclared identifier.
+// DeclarationError: (1651-1652): Undeclared identifier.
+// DeclarationError: (1662-1663): Undeclared identifier.
+// DeclarationError: (1673-1674): Undeclared identifier.
+// DeclarationError: (1684-1685): Undeclared identifier.
+// DeclarationError: (1695-1696): Undeclared identifier.
+// DeclarationError: (1706-1707): Undeclared identifier.
+// DeclarationError: (1717-1718): Undeclared identifier.
+// DeclarationError: (1728-1729): Undeclared identifier.
+// DeclarationError: (1739-1740): Undeclared identifier.
+// DeclarationError: (1750-1751): Undeclared identifier.
+// DeclarationError: (1761-1762): Undeclared identifier.
+// DeclarationError: (1772-1773): Undeclared identifier.
+// DeclarationError: (1783-1784): Undeclared identifier.
+// DeclarationError: (1794-1795): Undeclared identifier.
+// DeclarationError: (1805-1806): Undeclared identifier.
+// DeclarationError: (1816-1817): Undeclared identifier.
+// DeclarationError: (1827-1828): Undeclared identifier.
+// DeclarationError: (1838-1839): Undeclared identifier.
+// DeclarationError: (1849-1850): Undeclared identifier.
+// DeclarationError: (1860-1861): Undeclared identifier.
+// DeclarationError: (1871-1872): Undeclared identifier.
+// DeclarationError: (1882-1883): Undeclared identifier.
+// DeclarationError: (1893-1894): Undeclared identifier.
+// DeclarationError: (1904-1905): Undeclared identifier.
+// DeclarationError: (1915-1916): Undeclared identifier.
+// DeclarationError: (1926-1927): Undeclared identifier.
+// DeclarationError: (1937-1938): Undeclared identifier.
+// DeclarationError: (1948-1949): Undeclared identifier.
+// DeclarationError: (1959-1960): Undeclared identifier.
+// DeclarationError: (1970-1971): Undeclared identifier.
+// DeclarationError: (1981-1982): Undeclared identifier.
+// DeclarationError: (1992-1993): Undeclared identifier.
+// DeclarationError: (2003-2004): Undeclared identifier.
+// DeclarationError: (2014-2015): Undeclared identifier.
+// DeclarationError: (2025-2026): Undeclared identifier.
+// DeclarationError: (2036-2037): Undeclared identifier.
+// DeclarationError: (2047-2048): Undeclared identifier.
+// DeclarationError: (2058-2059): Undeclared identifier.
+// DeclarationError: (2069-2070): Undeclared identifier.
+// DeclarationError: (2080-2081): Undeclared identifier.
+// DeclarationError: (2091-2092): Undeclared identifier.
+// DeclarationError: (2102-2103): Undeclared identifier.
+// DeclarationError: (2113-2114): Undeclared identifier.
+// DeclarationError: (2124-2125): Undeclared identifier.
+// DeclarationError: (2135-2136): Undeclared identifier.
+// DeclarationError: (2146-2147): Undeclared identifier.
+// DeclarationError: (2157-2158): Undeclared identifier.
+// DeclarationError: (2168-2169): Undeclared identifier.
+// DeclarationError: (2179-2180): Undeclared identifier.
+// DeclarationError: (2190-2191): Undeclared identifier.
+// DeclarationError: (2201-2202): Undeclared identifier.
+// DeclarationError: (2212-2213): Undeclared identifier.
+// DeclarationError: (2223-2224): Undeclared identifier.
+// DeclarationError: (2234-2235): Undeclared identifier.
+// DeclarationError: (2245-2246): Undeclared identifier.
+// DeclarationError: (2256-2257): Undeclared identifier.
+// DeclarationError: (2267-2268): Undeclared identifier.
+// DeclarationError: (2278-2279): Undeclared identifier.
+// DeclarationError: (2289-2290): Undeclared identifier.
+// DeclarationError: (2300-2301): Undeclared identifier.
+// DeclarationError: (2311-2312): Undeclared identifier.
+// DeclarationError: (2322-2323): Undeclared identifier.
+// DeclarationError: (2333-2334): Undeclared identifier.
+// DeclarationError: (2344-2345): Undeclared identifier.
+// DeclarationError: (2355-2356): Undeclared identifier.
+// DeclarationError: (2366-2367): Undeclared identifier.
+// DeclarationError: (2377-2378): Undeclared identifier.
+// DeclarationError: (2388-2389): Undeclared identifier.
+// DeclarationError: (2399-2400): Undeclared identifier.
+// DeclarationError: (2410-2411): Undeclared identifier.
+// DeclarationError: (2421-2422): Undeclared identifier.
+// DeclarationError: (2432-2433): Undeclared identifier.
+// DeclarationError: (2443-2444): Undeclared identifier.
+// DeclarationError: (2454-2455): Undeclared identifier.
+// DeclarationError: (2465-2466): Undeclared identifier.
+// DeclarationError: (2476-2477): Undeclared identifier.
+// DeclarationError: (2487-2488): Undeclared identifier.
+// DeclarationError: (2498-2499): Undeclared identifier.
+// DeclarationError: (2509-2510): Undeclared identifier.
+// DeclarationError: (2520-2521): Undeclared identifier.
+// DeclarationError: (2531-2532): Undeclared identifier.
+// DeclarationError: (2542-2543): Undeclared identifier.
+// DeclarationError: (2553-2554): Undeclared identifier.
+// DeclarationError: (2564-2565): Undeclared identifier.
+// DeclarationError: (2575-2576): Undeclared identifier.
+// DeclarationError: (2586-2587): Undeclared identifier.
+// DeclarationError: (2597-2598): Undeclared identifier.
+// DeclarationError: (2608-2609): Undeclared identifier.
+// DeclarationError: (2619-2620): Undeclared identifier.
+// DeclarationError: (2630-2631): Undeclared identifier.
+// DeclarationError: (2641-2642): Undeclared identifier.
+// DeclarationError: (2652-2653): Undeclared identifier.
+// DeclarationError: (2663-2664): Undeclared identifier.
+// DeclarationError: (2674-2675): Undeclared identifier.
+// DeclarationError: (2685-2686): Undeclared identifier.
+// DeclarationError: (2696-2697): Undeclared identifier.
+// DeclarationError: (2707-2708): Undeclared identifier.
+// DeclarationError: (2718-2719): Undeclared identifier.
+// DeclarationError: (2729-2730): Undeclared identifier.
+// DeclarationError: (2740-2741): Undeclared identifier.
+// DeclarationError: (2751-2752): Undeclared identifier.
+// DeclarationError: (2762-2763): Undeclared identifier.
+// DeclarationError: (2773-2774): Undeclared identifier.
+// DeclarationError: (2784-2785): Undeclared identifier.
+// DeclarationError: (2795-2796): Undeclared identifier.
+// DeclarationError: (2806-2807): Undeclared identifier.
+// DeclarationError: (2817-2818): Undeclared identifier.
+// DeclarationError: (2828-2829): Undeclared identifier.
+// DeclarationError: (2839-2840): Undeclared identifier.
+// Warning: There are more than 256 errors. Aborting.
diff --git a/test/libsolidity/syntaxTests/more_than_256_syntaxerrors.sol b/test/libsolidity/syntaxTests/more_than_256_syntaxerrors.sol
new file mode 100644
index 00000000..2c9b8a42
--- /dev/null
+++ b/test/libsolidity/syntaxTests/more_than_256_syntaxerrors.sol
@@ -0,0 +1,524 @@
+contract C {
+ function f() {
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ continue;
+ }
+}
+// ----
+// SyntaxError: (34-42): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (48-56): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (62-70): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (76-84): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (90-98): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (104-112): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (118-126): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (132-140): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (146-154): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (160-168): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (174-182): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (188-196): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (202-210): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (216-224): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (230-238): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (244-252): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (258-266): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (272-280): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (286-294): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (300-308): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (314-322): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (328-336): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (342-350): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (356-364): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (370-378): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (384-392): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (398-406): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (412-420): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (426-434): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (440-448): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (454-462): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (468-476): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (482-490): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (496-504): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (510-518): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (524-532): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (538-546): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (552-560): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (566-574): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (580-588): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (594-602): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (608-616): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (622-630): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (636-644): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (650-658): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (664-672): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (678-686): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (692-700): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (706-714): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (720-728): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (734-742): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (748-756): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (762-770): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (776-784): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (790-798): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (804-812): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (818-826): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (832-840): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (846-854): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (860-868): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (874-882): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (888-896): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (902-910): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (916-924): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (930-938): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (944-952): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (958-966): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (972-980): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (986-994): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1000-1008): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1014-1022): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1028-1036): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1042-1050): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1056-1064): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1070-1078): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1084-1092): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1098-1106): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1112-1120): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1126-1134): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1140-1148): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1154-1162): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1168-1176): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1182-1190): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1196-1204): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1210-1218): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1224-1232): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1238-1246): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1252-1260): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1266-1274): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1280-1288): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1294-1302): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1308-1316): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1322-1330): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1336-1344): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1350-1358): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1364-1372): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1378-1386): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1392-1400): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1406-1414): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1420-1428): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1434-1442): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1448-1456): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1462-1470): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1476-1484): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1490-1498): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1504-1512): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1518-1526): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1532-1540): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1546-1554): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1560-1568): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1574-1582): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1588-1596): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1602-1610): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1616-1624): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1630-1638): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1644-1652): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1658-1666): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1672-1680): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1686-1694): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1700-1708): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1714-1722): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1728-1736): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1742-1750): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1756-1764): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1770-1778): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1784-1792): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1798-1806): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1812-1820): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1826-1834): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1840-1848): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1854-1862): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1868-1876): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1882-1890): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1896-1904): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1910-1918): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1924-1932): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1938-1946): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1952-1960): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1966-1974): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1980-1988): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (1994-2002): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2008-2016): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2022-2030): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2036-2044): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2050-2058): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2064-2072): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2078-2086): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2092-2100): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2106-2114): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2120-2128): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2134-2142): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2148-2156): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2162-2170): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2176-2184): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2190-2198): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2204-2212): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2218-2226): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2232-2240): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2246-2254): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2260-2268): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2274-2282): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2288-2296): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2302-2310): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2316-2324): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2330-2338): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2344-2352): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2358-2366): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2372-2380): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2386-2394): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2400-2408): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2414-2422): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2428-2436): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2442-2450): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2456-2464): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2470-2478): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2484-2492): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2498-2506): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2512-2520): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2526-2534): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2540-2548): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2554-2562): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2568-2576): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2582-2590): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2596-2604): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2610-2618): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2624-2632): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2638-2646): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2652-2660): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2666-2674): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2680-2688): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2694-2702): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2708-2716): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2722-2730): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2736-2744): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2750-2758): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2764-2772): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2778-2786): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2792-2800): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2806-2814): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2820-2828): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2834-2842): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2848-2856): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2862-2870): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2876-2884): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2890-2898): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2904-2912): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2918-2926): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2932-2940): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2946-2954): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2960-2968): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2974-2982): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (2988-2996): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3002-3010): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3016-3024): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3030-3038): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3044-3052): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3058-3066): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3072-3080): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3086-3094): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3100-3108): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3114-3122): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3128-3136): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3142-3150): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3156-3164): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3170-3178): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3184-3192): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3198-3206): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3212-3220): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3226-3234): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3240-3248): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3254-3262): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3268-3276): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3282-3290): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3296-3304): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3310-3318): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3324-3332): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3338-3346): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3352-3360): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3366-3374): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3380-3388): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3394-3402): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3408-3416): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3422-3430): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3436-3444): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3450-3458): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3464-3472): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3478-3486): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3492-3500): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3506-3514): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3520-3528): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3534-3542): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3548-3556): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3562-3570): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3576-3584): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3590-3598): "continue" has to be in a "for" or "while" loop.
+// SyntaxError: (3604-3612): "continue" has to be in a "for" or "while" loop.
+// Warning: There are more than 256 errors. Aborting.
diff --git a/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol b/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol
new file mode 100644
index 00000000..9f714aea
--- /dev/null
+++ b/test/libsolidity/syntaxTests/parsing/constructor_allowed_this.sol
@@ -0,0 +1,28 @@
+contract A {
+ function a() public pure {
+ }
+}
+contract B {
+ constructor(address) public {
+ }
+ function b(address) public returns (A) {
+ return new A();
+ }
+}
+contract C {
+ B m_b;
+ C m_c;
+ constructor(C other_c) public {
+ m_c = other_c;
+ m_b = new B(this);
+ m_b.b(this).a();
+ g(this).f();
+ other_c.f();
+ m_c.f();
+ }
+ function f() public pure {
+ }
+ function g(C) public view returns (C) {
+ return m_c;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/parsing/constructor_super.sol b/test/libsolidity/syntaxTests/parsing/constructor_super.sol
new file mode 100644
index 00000000..fa1be187
--- /dev/null
+++ b/test/libsolidity/syntaxTests/parsing/constructor_super.sol
@@ -0,0 +1,10 @@
+contract A {
+ function x() pure internal {}
+}
+
+contract B is A {
+ constructor() public {
+ // used to trigger warning about using ``this`` in constructor
+ super.x();
+ }
+}
diff --git a/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol b/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol
new file mode 100644
index 00000000..fd3067e3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/parsing/missing_variable_name_in_declaration.sol
@@ -0,0 +1,5 @@
+contract test {
+ uint256 ;
+}
+// ----
+// ParserError: (28-28): Expected identifier, got 'Semicolon'
diff --git a/test/libsolidity/syntaxTests/parsing/return_var.sol b/test/libsolidity/syntaxTests/parsing/return_var.sol
new file mode 100644
index 00000000..47ac9ef0
--- /dev/null
+++ b/test/libsolidity/syntaxTests/parsing/return_var.sol
@@ -0,0 +1,25 @@
+contract C {
+ function f() returns(var) {}
+ function f() returns(var x) {}
+ function f() returns(var x, uint y) {}
+ function f() returns(uint x, var y) {}
+ function f() returns(var x, var y) {}
+ function f() public pure returns (var storage) {}
+ function f() public pure returns (var storage x) {}
+ 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.
diff --git a/test/libsolidity/syntaxTests/parsing/smoke_test.sol b/test/libsolidity/syntaxTests/parsing/smoke_test.sol
new file mode 100644
index 00000000..d328b167
--- /dev/null
+++ b/test/libsolidity/syntaxTests/parsing/smoke_test.sol
@@ -0,0 +1,4 @@
+contract test {
+ uint256 stateVariable1;
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol b/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol
new file mode 100644
index 00000000..e041247d
--- /dev/null
+++ b/test/libsolidity/syntaxTests/parsing/var_in_function_arguments.sol
@@ -0,0 +1,25 @@
+contract C {
+ function f(var) public pure {}
+ function f(var x) public pure {}
+ function f(var x, var y) public pure {}
+ function f(uint x, var y) public pure {}
+ function f(var x, uint y) public pure {}
+ function f(var storage) public pure {}
+ function f(var storage x) public pure {}
+ 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.
diff --git a/test/libsolidity/syntaxTests/parsing/var_storage_var.sol b/test/libsolidity/syntaxTests/parsing/var_storage_var.sol
new file mode 100644
index 00000000..431d4ca5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/parsing/var_storage_var.sol
@@ -0,0 +1,5 @@
+contract C {
+ var a;
+}
+// ----
+// ParserError: (17-17): Function, variable, struct or modifier declaration expected.
diff --git a/test/libsolidity/syntaxTests/scoping/double_function_declaration.sol b/test/libsolidity/syntaxTests/scoping/double_function_declaration.sol
new file mode 100644
index 00000000..dfd67aaa
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/double_function_declaration.sol
@@ -0,0 +1,6 @@
+contract test {
+ function fun() public { }
+ function fun() public { }
+}
+// ----
+// DeclarationError: (20-45): Function with same name and arguments defined twice.
diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol
new file mode 100644
index 00000000..d90ec2d7
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope.sol
@@ -0,0 +1,8 @@
+contract test {
+ function f() pure public {
+ { uint x; }
+ { uint x; }
+ }
+}
+// ----
+// DeclarationError: (77-83): Identifier already declared.
diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol
new file mode 100644
index 00000000..06bfe7be
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_050.sol
@@ -0,0 +1,10 @@
+pragma experimental "v0.5.0";
+contract test {
+ function f() pure public {
+ { uint x; }
+ { uint x; }
+ }
+}
+// ----
+// Warning: (87-93): Unused local variable.
+// Warning: (107-113): Unused local variable.
diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol
new file mode 100644
index 00000000..1a5ff2f9
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation.sol
@@ -0,0 +1,8 @@
+contract test {
+ function f() pure public {
+ { uint x; }
+ uint x;
+ }
+}
+// ----
+// DeclarationError: (75-81): Identifier already declared.
diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol
new file mode 100644
index 00000000..20ea0349
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_disjoint_scope_activation_050.sol
@@ -0,0 +1,10 @@
+pragma experimental "v0.5.0";
+contract test {
+ function f() pure public {
+ { uint x; }
+ uint x;
+ }
+}
+// ----
+// Warning: (87-93): Unused local variable.
+// Warning: (105-111): Unused local variable.
diff --git a/test/libsolidity/syntaxTests/scoping/name_shadowing.sol b/test/libsolidity/syntaxTests/scoping/name_shadowing.sol
new file mode 100644
index 00000000..67ada4a4
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/name_shadowing.sol
@@ -0,0 +1,6 @@
+contract test {
+ uint256 variable;
+ function f() pure public { uint32 variable; variable = 2; }
+}
+// ----
+// Warning: (69-84): This declaration shadows an existing declaration.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping.sol b/test/libsolidity/syntaxTests/scoping/scoping.sol
new file mode 100644
index 00000000..34b055d9
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/scoping.sol
@@ -0,0 +1,11 @@
+pragma experimental "v0.5.0";
+contract test {
+ function f() public {
+ {
+ uint256 x;
+ }
+ x = 2;
+ }
+}
+// ----
+// DeclarationError: (123-124): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_activation.sol b/test/libsolidity/syntaxTests/scoping/scoping_activation.sol
new file mode 100644
index 00000000..7334bc49
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/scoping_activation.sol
@@ -0,0 +1,9 @@
+pragma experimental "v0.5.0";
+contract test {
+ function f() pure public {
+ x = 3;
+ uint x;
+ }
+}
+// ----
+// DeclarationError: (85-86): Undeclared identifier. Did you mean "x"?
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol b/test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol
new file mode 100644
index 00000000..d893a889
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/scoping_activation_old.sol
@@ -0,0 +1,6 @@
+contract test {
+ function f() pure public {
+ x = 3;
+ uint x;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for.sol b/test/libsolidity/syntaxTests/scoping/scoping_for.sol
new file mode 100644
index 00000000..6e5b7095
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/scoping_for.sol
@@ -0,0 +1,8 @@
+pragma experimental "v0.5.0";
+contract test {
+ function f() pure public {
+ for (uint x = 0; x < 10; x ++){
+ x = 2;
+ }
+ }
+}
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for2.sol b/test/libsolidity/syntaxTests/scoping/scoping_for2.sol
new file mode 100644
index 00000000..eb74b8ab
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/scoping_for2.sol
@@ -0,0 +1,7 @@
+pragma experimental "v0.5.0";
+contract test {
+ function f() pure public {
+ for (uint x = 0; x < 10; x ++)
+ x = 2;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for3.sol b/test/libsolidity/syntaxTests/scoping/scoping_for3.sol
new file mode 100644
index 00000000..1814cb47
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/scoping_for3.sol
@@ -0,0 +1,11 @@
+pragma experimental "v0.5.0";
+contract test {
+ function f() pure public {
+ for (uint x = 0; x < 10; x ++){
+ x = 2;
+ }
+ x = 4;
+ }
+}
+// ----
+// DeclarationError: (154-155): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol b/test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol
new file mode 100644
index 00000000..3e80b385
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/scoping_for_decl_in_body.sol
@@ -0,0 +1,10 @@
+pragma experimental "v0.5.0";
+contract test {
+ function f() pure public {
+ for (;; y++){
+ uint y = 3;
+ }
+ }
+}
+// ----
+// DeclarationError: (93-94): Undeclared identifier.
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_old.sol b/test/libsolidity/syntaxTests/scoping/scoping_old.sol
new file mode 100644
index 00000000..83f6b60b
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/scoping_old.sol
@@ -0,0 +1,6 @@
+contract test {
+ function f() pure public {
+ x = 4;
+ uint256 x = 2;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_self_use.sol b/test/libsolidity/syntaxTests/scoping/scoping_self_use.sol
new file mode 100644
index 00000000..9e2c0171
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/scoping_self_use.sol
@@ -0,0 +1,5 @@
+contract test {
+ function f() pure public {
+ uint a = a;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol b/test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol
new file mode 100644
index 00000000..ab3dcefb
--- /dev/null
+++ b/test/libsolidity/syntaxTests/scoping/scoping_self_use_050.sol
@@ -0,0 +1,8 @@
+pragma experimental "v0.5.0";
+contract test {
+ function f() pure public {
+ uint a = a;
+ }
+}
+// ----
+// DeclarationError: (94-95): Undeclared identifier. Did you mean "a"?
diff --git a/test/libsolidity/syntaxTests/signed_rational_modulus.sol b/test/libsolidity/syntaxTests/signed_rational_modulus.sol
new file mode 100644
index 00000000..b37d33d0
--- /dev/null
+++ b/test/libsolidity/syntaxTests/signed_rational_modulus.sol
@@ -0,0 +1,8 @@
+contract test {
+ function f() public pure {
+ fixed a = 0.42578125 % -0.4271087646484375;
+ fixed b = .5 % a;
+ fixed c = a % b;
+ a; b; c;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/smoke_test.sol b/test/libsolidity/syntaxTests/smoke_test.sol
new file mode 100644
index 00000000..6abaff18
--- /dev/null
+++ b/test/libsolidity/syntaxTests/smoke_test.sol
@@ -0,0 +1,6 @@
+contract test {
+ uint256 stateVariable1;
+ function fun(uint256 arg1) public { uint256 y; y = arg1; }
+}
+// ----
+// Warning: (42-100): Function state mutability can be restricted to pure
diff --git a/test/libsolidity/syntaxTests/specialFunctions/abi_encode_structs.sol b/test/libsolidity/syntaxTests/specialFunctions/abi_encode_structs.sol
new file mode 100644
index 00000000..d9eebee4
--- /dev/null
+++ b/test/libsolidity/syntaxTests/specialFunctions/abi_encode_structs.sol
@@ -0,0 +1,17 @@
+contract C {
+ struct S { uint x; }
+ S s;
+ struct T { uint y; }
+ T t;
+ function f() public view {
+ abi.encode(s, t);
+ }
+ function g() public view {
+ abi.encodePacked(s, t);
+ }
+}
+// ----
+// TypeError: (131-132): This type cannot be encoded.
+// TypeError: (134-135): This type cannot be encoded.
+// TypeError: (200-201): This type cannot be encoded.
+// TypeError: (203-204): This type cannot be encoded.
diff --git a/test/libsolidity/syntaxTests/specialFunctions/abi_encode_structs_abiv2.sol b/test/libsolidity/syntaxTests/specialFunctions/abi_encode_structs_abiv2.sol
new file mode 100644
index 00000000..d6cf60e4
--- /dev/null
+++ b/test/libsolidity/syntaxTests/specialFunctions/abi_encode_structs_abiv2.sol
@@ -0,0 +1,18 @@
+pragma experimental ABIEncoderV2;
+
+contract C {
+ struct S { uint x; }
+ S s;
+ struct T { uint y; }
+ T t;
+ function f() public view {
+ abi.encode(s, t);
+ }
+ function g() public view {
+ abi.encodePacked(s, t);
+ }
+}
+// ----
+// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
+// TypeError: (235-236): This type cannot be encoded.
+// TypeError: (238-239): This type cannot be encoded.
diff --git a/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol
new file mode 100644
index 00000000..c98d7a57
--- /dev/null
+++ b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_internal_functions.sol
@@ -0,0 +1,11 @@
+contract C {
+ function f() public pure {
+ bytes32 h = keccak256(keccak256, f, this.f.gas, block.blockhash);
+ h;
+ }
+}
+// ----
+// TypeError: (74-83): This type cannot be encoded.
+// TypeError: (85-86): This type cannot be encoded.
+// TypeError: (88-98): This type cannot be encoded.
+// TypeError: (100-115): This type cannot be encoded.
diff --git a/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_special_types.sol b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_special_types.sol
new file mode 100644
index 00000000..f1b5606e
--- /dev/null
+++ b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_special_types.sol
@@ -0,0 +1,13 @@
+contract C {
+ function f() public pure {
+ bool a = address(this).call(address(this).delegatecall, super);
+ bool b = address(this).delegatecall(log0, tx, mulmod);
+ a; b;
+ }
+}
+// ----
+// TypeError: (80-106): This type cannot be encoded.
+// TypeError: (108-113): This type cannot be encoded.
+// TypeError: (160-164): This type cannot be encoded.
+// TypeError: (166-168): This type cannot be encoded.
+// TypeError: (170-176): This type cannot be encoded.
diff --git a/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_structs.sol b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_structs.sol
new file mode 100644
index 00000000..fa910260
--- /dev/null
+++ b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_structs.sol
@@ -0,0 +1,13 @@
+contract C {
+ struct S { uint x; }
+ S s;
+ struct T { uint y; }
+ T t;
+ function f() public view {
+ bytes32 a = sha256(s, t);
+ a;
+ }
+}
+// ----
+// TypeError: (139-140): This type cannot be encoded.
+// TypeError: (142-143): This type cannot be encoded.
diff --git a/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_structs_abiv2.sol b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_structs_abiv2.sol
new file mode 100644
index 00000000..1187ce4a
--- /dev/null
+++ b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_structs_abiv2.sol
@@ -0,0 +1,16 @@
+pragma experimental ABIEncoderV2;
+
+contract C {
+ struct S { uint x; }
+ S s;
+ struct T { uint y; }
+ T t;
+ function f() public view {
+ bytes32 a = sha256(s, t);
+ a;
+ }
+}
+// ----
+// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
+// TypeError: (174-175): This type cannot be encoded.
+// TypeError: (177-178): This type cannot be encoded.
diff --git a/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_types.sol b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_types.sol
new file mode 100644
index 00000000..d10c1718
--- /dev/null
+++ b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_types.sol
@@ -0,0 +1,17 @@
+contract C {
+ struct S { uint x; }
+ S s;
+ struct T { }
+ T t;
+ enum A { X, Y }
+ function f() public pure {
+ bool a = address(this).delegatecall(S, A, A.X, T, uint, uint[]);
+ }
+}
+// ----
+// Warning: (51-63): Defining empty structs is deprecated.
+// TypeError: (168-169): This type cannot be encoded.
+// TypeError: (171-172): This type cannot be encoded.
+// TypeError: (179-180): This type cannot be encoded.
+// TypeError: (182-186): This type cannot be encoded.
+// TypeError: (188-194): This type cannot be encoded.
diff --git a/test/libsolidity/syntaxTests/specialFunctions/types_without_encoding_problems.sol b/test/libsolidity/syntaxTests/specialFunctions/types_without_encoding_problems.sol
new file mode 100644
index 00000000..c8364548
--- /dev/null
+++ b/test/libsolidity/syntaxTests/specialFunctions/types_without_encoding_problems.sol
@@ -0,0 +1,9 @@
+contract C {
+ uint[3] sarr;
+ function f() view public {
+ uint[3] memory arr;
+ bytes32 h = keccak256(this.f, arr, sarr);
+ h;
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/structs/recursion/multi_struct_composition.sol b/test/libsolidity/syntaxTests/structs/recursion/multi_struct_composition.sol
new file mode 100644
index 00000000..895bb6c5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/structs/recursion/multi_struct_composition.sol
@@ -0,0 +1,15 @@
+pragma experimental ABIEncoderV2;
+
+contract C {
+ struct T { U u; V v; }
+
+ struct U { W w; }
+
+ struct V { W w; }
+
+ struct W { uint x; }
+
+ function f(T) public pure { }
+}
+// ----
+// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
diff --git a/test/libsolidity/syntaxTests/structs/recursion/parallel_structs.sol b/test/libsolidity/syntaxTests/structs/recursion/parallel_structs.sol
new file mode 100644
index 00000000..96362ef0
--- /dev/null
+++ b/test/libsolidity/syntaxTests/structs/recursion/parallel_structs.sol
@@ -0,0 +1,15 @@
+pragma experimental ABIEncoderV2;
+
+contract TestContract
+{
+ struct SubStruct {
+ uint256 id;
+ }
+ struct TestStruct {
+ SubStruct subStruct1;
+ SubStruct subStruct2;
+ }
+ function addTestStruct(TestStruct) public pure {}
+}
+// ----
+// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
diff --git a/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs.sol b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs.sol
new file mode 100644
index 00000000..4966a731
--- /dev/null
+++ b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs.sol
@@ -0,0 +1,7 @@
+contract C {
+ struct S { uint a; S[] sub; }
+ function f() public pure returns (uint, S) {
+ }
+}
+// ----
+// TypeError: (91-92): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs2.sol b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs2.sol
new file mode 100644
index 00000000..68113924
--- /dev/null
+++ b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs2.sol
@@ -0,0 +1,7 @@
+contract C {
+ struct S { uint a; S[2][] sub; }
+ function f() public pure returns (uint, S) {
+ }
+}
+// ----
+// TypeError: (94-95): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs3.sol b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs3.sol
new file mode 100644
index 00000000..47690d9b
--- /dev/null
+++ b/test/libsolidity/syntaxTests/structs/recursion/return_recursive_structs3.sol
@@ -0,0 +1,8 @@
+contract C {
+ struct S { uint a; S[][][] sub; }
+ struct T { S s; }
+ function f() public pure returns (uint x, T t) {
+ }
+}
+// ----
+// TypeError: (119-122): Internal or recursive type is not allowed for public or external functions.
diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive.sol
new file mode 100644
index 00000000..bcffe383
--- /dev/null
+++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_directly_recursive.sol
@@ -0,0 +1,8 @@
+contract Test {
+ struct MyStructName {
+ address addr;
+ MyStructName x;
+ }
+}
+// ----
+// TypeError: (20-93): Recursive struct definition.
diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive.sol
new file mode 100644
index 00000000..64dab8d0
--- /dev/null
+++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_indirectly_recursive.sol
@@ -0,0 +1,12 @@
+contract Test {
+ struct MyStructName1 {
+ address addr;
+ uint256 count;
+ MyStructName2 x;
+ }
+ struct MyStructName2 {
+ MyStructName1 x;
+ }
+}
+// ----
+// TypeError: (20-118): Recursive struct definition.
diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_not_really_recursive.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_not_really_recursive.sol
new file mode 100644
index 00000000..6ec4ee01
--- /dev/null
+++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_not_really_recursive.sol
@@ -0,0 +1,4 @@
+contract Test {
+ struct S1 { uint a; }
+ struct S2 { S1 x; S1 y; }
+}
diff --git a/test/libsolidity/syntaxTests/structs/recursion/struct_definition_recursion_via_mapping.sol b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_recursion_via_mapping.sol
new file mode 100644
index 00000000..926981b3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/structs/recursion/struct_definition_recursion_via_mapping.sol
@@ -0,0 +1,7 @@
+contract Test {
+ struct MyStructName1 {
+ address addr;
+ uint256 count;
+ mapping(uint => MyStructName1) x;
+ }
+}
diff --git a/test/libsolidity/syntaxTests/tight_packing_literals.sol b/test/libsolidity/syntaxTests/tight_packing_literals.sol
new file mode 100644
index 00000000..8258a8a6
--- /dev/null
+++ b/test/libsolidity/syntaxTests/tight_packing_literals.sol
@@ -0,0 +1,25 @@
+contract C {
+ function f() pure public returns (bytes32) {
+ return keccak256(1);
+ }
+ function g() pure public returns (bytes32) {
+ return sha3(1);
+ }
+ function h() pure public returns (bytes32) {
+ return sha256(1);
+ }
+ function j() pure public returns (bytes32) {
+ return ripemd160(1);
+ }
+ function k() pure public returns (bytes) {
+ return abi.encodePacked(1);
+ }
+}
+
+// ----
+// Warning: (87-88): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning.
+// Warning: (161-168): "sha3" has been deprecated in favour of "keccak256"
+// Warning: (166-167): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning.
+// Warning: (247-248): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning.
+// Warning: (331-332): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning.
+// Warning: (420-421): The type of "int_const 1" was inferred as uint8. This is probably not desired. Use an explicit type to silence this warning.
diff --git a/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol b/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol
new file mode 100644
index 00000000..46407f71
--- /dev/null
+++ b/test/libsolidity/syntaxTests/tight_packing_literals_fine.sol
@@ -0,0 +1,11 @@
+contract C {
+ function f() pure public returns (bytes32) {
+ return keccak256(uint8(1));
+ }
+ function g() pure public returns (bytes) {
+ return abi.encode(1);
+ }
+ function h() pure public returns (bytes) {
+ return abi.encodePacked(uint8(1));
+ }
+}
diff --git a/test/libsolidity/syntaxTests/types/rational_number_array_index_limit.sol b/test/libsolidity/syntaxTests/types/rational_number_array_index_limit.sol
new file mode 100644
index 00000000..45ede998
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/rational_number_array_index_limit.sol
@@ -0,0 +1,5 @@
+contract c {
+ uint[2**253] data;
+}
+// ----
+// Warning: (17-34): Variable covers a large part of storage and thus makes collisions likely. Either use mappings or dynamic arrays and allow their size to be increased only in small quantities per transaction.
diff --git a/test/libsolidity/syntaxTests/types/rational_number_bitshift_limit.sol b/test/libsolidity/syntaxTests/types/rational_number_bitshift_limit.sol
new file mode 100644
index 00000000..94981aa0
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/rational_number_bitshift_limit.sol
@@ -0,0 +1,13 @@
+contract c {
+ function f() public pure {
+ int a;
+ a = 1 << 4095; // shift is fine, but result too large
+ a = 1 << 4096; // too large
+ a = (1E1233) << 2; // too large
+ }
+}
+// ----
+// TypeError: (71-80): Type int_const 5221...(1225 digits omitted)...5168 is not implicitly convertible to expected type int256.
+// TypeError: (133-142): Operator << not compatible with types int_const 1 and int_const 4096
+// TypeError: (169-182): Operator << not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const 2
+// TypeError: (169-182): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256.
diff --git a/test/libsolidity/syntaxTests/types/rational_number_div_limit.sol b/test/libsolidity/syntaxTests/types/rational_number_div_limit.sol
new file mode 100644
index 00000000..1b0b5f94
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/rational_number_div_limit.sol
@@ -0,0 +1,9 @@
+contract c {
+ function f() public pure {
+ int a;
+ a = 1/(2<<4094)/(2<<4094);
+ }
+}
+// ----
+// TypeError: (71-92): Operator / not compatible with types rational_const 1 / 5221...(1225 digits omitted)...5168 and int_const 5221...(1225 digits omitted)...5168
+// TypeError: (71-92): Type rational_const 1 / 5221...(1225 digits omitted)...5168 is not implicitly convertible to expected type int256. Try converting to type ufixed8x80 or use an explicit conversion.
diff --git a/test/libsolidity/syntaxTests/types/rational_number_exp_limit.sol b/test/libsolidity/syntaxTests/types/rational_number_exp_limit.sol
new file mode 100644
index 00000000..6785f580
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/rational_number_exp_limit.sol
@@ -0,0 +1,50 @@
+contract c {
+ function f() public pure {
+ int a;
+ a = 4 ** 4 ** 2 ** 4 ** 4 ** 4 ** 4;
+ a = -4 ** 4 ** 2 ** 4 ** 4 ** 4 ** 4 ** 4;
+ a = 4 ** (-(2 ** 4 ** 4 ** 4 ** 4 ** 4));
+ a = 0 ** 1E1233; // fine
+ a = 1 ** 1E1233; // fine
+ a = -1 ** 1E1233; // fine
+ a = 2 ** 1E1233;
+ a = -2 ** 1E1233;
+ a = 2 ** -1E1233;
+ a = -2 ** -1E1233;
+ a = 1E1233 ** 2;
+ a = -1E1233 ** 2;
+ a = 1E1233 ** -2;
+ a = -1E1233 ** -2;
+ a = 1E1233 ** 1E1233;
+ a = 1E1233 ** -1E1233;
+ a = -1E1233 ** 1E1233;
+ a = -1E1233 ** -1E1233;
+ }
+}
+// ----
+// TypeError: (71-102): Operator ** not compatible with types int_const 1797...(301 digits omitted)...7216 and int_const 4
+// TypeError: (71-102): Type int_const 1797...(301 digits omitted)...7216 is not implicitly convertible to expected type int256.
+// TypeError: (116-148): Operator ** not compatible with types int_const 1797...(301 digits omitted)...7216 and int_const 4
+// TypeError: (116-153): Operator ** not compatible with types int_const 1797...(301 digits omitted)...7216 and int_const 4
+// TypeError: (116-153): Type int_const 1797...(301 digits omitted)...7216 is not implicitly convertible to expected type int256.
+// TypeError: (167-203): Operator ** not compatible with types int_const 4 and int_const -179...(302 digits omitted)...7216
+// TypeError: (317-328): Operator ** not compatible with types int_const 2 and int_const 1000...(1226 digits omitted)...0000
+// TypeError: (342-354): Operator ** not compatible with types int_const -2 and int_const 1000...(1226 digits omitted)...0000
+// TypeError: (368-380): Operator ** not compatible with types int_const 2 and int_const -100...(1227 digits omitted)...0000
+// TypeError: (394-407): Operator ** not compatible with types int_const -2 and int_const -100...(1227 digits omitted)...0000
+// TypeError: (421-432): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const 2
+// TypeError: (421-432): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256.
+// TypeError: (446-458): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const 2
+// TypeError: (446-458): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256.
+// TypeError: (472-484): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const -2
+// TypeError: (472-484): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256.
+// TypeError: (498-511): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const -2
+// TypeError: (498-511): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256.
+// TypeError: (525-541): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const 1000...(1226 digits omitted)...0000
+// TypeError: (525-541): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256.
+// TypeError: (555-572): Operator ** not compatible with types int_const 1000...(1226 digits omitted)...0000 and int_const -100...(1227 digits omitted)...0000
+// TypeError: (555-572): Type int_const 1000...(1226 digits omitted)...0000 is not implicitly convertible to expected type int256.
+// TypeError: (586-603): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const 1000...(1226 digits omitted)...0000
+// TypeError: (586-603): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256.
+// TypeError: (617-635): Operator ** not compatible with types int_const -100...(1227 digits omitted)...0000 and int_const -100...(1227 digits omitted)...0000
+// TypeError: (617-635): Type int_const -100...(1227 digits omitted)...0000 is not implicitly convertible to expected type int256.
diff --git a/test/libsolidity/syntaxTests/types/rational_number_literal_limit_1.sol b/test/libsolidity/syntaxTests/types/rational_number_literal_limit_1.sol
new file mode 100644
index 00000000..233857a3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/rational_number_literal_limit_1.sol
@@ -0,0 +1,9 @@
+contract c {
+ function bignum() public {
+ uint256 a;
+ a = 1e1233 / 1e1233; // 1e1233 is still fine
+ a = 1e1234; // 1e1234 is too big
+ }
+}
+// ----
+// TypeError: (128-134): Invalid literal value.
diff --git a/test/libsolidity/syntaxTests/types/rational_number_literal_limit_2.sol b/test/libsolidity/syntaxTests/types/rational_number_literal_limit_2.sol
new file mode 100644
index 00000000..16673924
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/rational_number_literal_limit_2.sol
@@ -0,0 +1,9 @@
+contract c {
+ function bignum() public {
+ uint a;
+ a = 134562324532464234452335168163516E1200 / 134562324532464234452335168163516E1200; // still fine
+ a = 1345623245324642344523351681635168E1200; // too large
+ }
+}
+// ----
+// TypeError: (179-218): Invalid literal value.
diff --git a/test/libsolidity/syntaxTests/types/rational_number_literal_limit_3.sol b/test/libsolidity/syntaxTests/types/rational_number_literal_limit_3.sol
new file mode 100644
index 00000000..5a696171
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/rational_number_literal_limit_3.sol
@@ -0,0 +1,9 @@
+contract c {
+ function bignum() public {
+ uint a;
+ a = 134562324532464.234452335168163517E1200 / 134562324532464.234452335168163517E1200; // still fine
+ a = 134562324532464.2344523351681635177E1200; // too large
+ }
+}
+// ----
+// TypeError: (181-221): Invalid literal value.
diff --git a/test/libsolidity/syntaxTests/types/rational_number_mul_limit.sol b/test/libsolidity/syntaxTests/types/rational_number_mul_limit.sol
new file mode 100644
index 00000000..bbed94b5
--- /dev/null
+++ b/test/libsolidity/syntaxTests/types/rational_number_mul_limit.sol
@@ -0,0 +1,9 @@
+contract c {
+ function f() public pure {
+ int a;
+ a = (1<<4095)*(1<<4095);
+ }
+}
+// ----
+// TypeError: (71-90): Operator * not compatible with types int_const 5221...(1225 digits omitted)...5168 and int_const 5221...(1225 digits omitted)...5168
+// TypeError: (71-90): Type int_const 5221...(1225 digits omitted)...5168 is not implicitly convertible to expected type int256.
diff --git a/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode.sol b/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode.sol
new file mode 100644
index 00000000..ca7db42e
--- /dev/null
+++ b/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode.sol
@@ -0,0 +1,8 @@
+contract C {
+ function f() pure public returns (bytes r) {
+ r = abi.encode(1, 2);
+ r = abi.encodePacked(f());
+ r = abi.encodeWithSelector(0x12345678, 1);
+ r = abi.encodeWithSignature("f(uint256)", 4);
+ }
+}
diff --git a/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode_arguments.sol b/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode_arguments.sol
new file mode 100644
index 00000000..547362c3
--- /dev/null
+++ b/test/libsolidity/syntaxTests/viewPure/view_pure_abi_encode_arguments.sol
@@ -0,0 +1,36 @@
+contract C {
+ uint x;
+ function gView() public view returns (uint) { return x; }
+ function gNonPayable() public returns (uint) { x = 4; return 0; }
+
+ function f1() view public returns (bytes) {
+ return abi.encode(gView());
+ }
+ function f2() view public returns (bytes) {
+ return abi.encodePacked(gView());
+ }
+ function f3() view public returns (bytes) {
+ return abi.encodeWithSelector(0x12345678, gView());
+ }
+ function f4() view public returns (bytes) {
+ return abi.encodeWithSignature("f(uint256)", gView());
+ }
+ function g1() public returns (bytes) {
+ return abi.encode(gNonPayable());
+ }
+ function g2() public returns (bytes) {
+ return abi.encodePacked(gNonPayable());
+ }
+ function g3() public returns (bytes) {
+ return abi.encodeWithSelector(0x12345678, gNonPayable());
+ }
+ function g4() public returns (bytes) {
+ return abi.encodeWithSignature("f(uint256)", gNonPayable());
+ }
+ // This will generate the only warning.
+ function check() public returns (bytes) {
+ return abi.encode(2);
+ }
+}
+// ----
+// Warning: (1044-1121): Function state mutability can be restricted to pure
diff --git a/test/libsolidity/syntaxTests/virtualLookup/modifiers_in_libraries.sol b/test/libsolidity/syntaxTests/virtualLookup/modifiers_in_libraries.sol
new file mode 100644
index 00000000..b033fd0c
--- /dev/null
+++ b/test/libsolidity/syntaxTests/virtualLookup/modifiers_in_libraries.sol
@@ -0,0 +1,14 @@
+library WithModifier {
+ modifier mod() { require(msg.value > 10 ether); _; }
+ function withMod(uint self) mod() internal view { require(self > 0); }
+}
+
+contract Test {
+ using WithModifier for *;
+
+ function f(uint _value) public payable {
+ _value.withMod();
+ WithModifier.withMod(_value);
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/visibility/external_library_function.sol b/test/libsolidity/syntaxTests/visibility/external_library_function.sol
new file mode 100644
index 00000000..110e74db
--- /dev/null
+++ b/test/libsolidity/syntaxTests/visibility/external_library_function.sol
@@ -0,0 +1,14 @@
+library L {
+ function f(uint) pure external {}
+}
+
+contract C {
+ using L for *;
+
+ function f() public pure {
+ L.f(2);
+ uint x;
+ x.f();
+ }
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_default.sol b/test/libsolidity/syntaxTests/visibility/interface/function_default.sol
new file mode 100644
index 00000000..72ce3b40
--- /dev/null
+++ b/test/libsolidity/syntaxTests/visibility/interface/function_default.sol
@@ -0,0 +1,6 @@
+interface I {
+ function f();
+}
+// ----
+// Warning: (15-28): Functions in interfaces should be declared external.
+// Warning: (15-28): No visibility specified. Defaulting to "public". In interfaces it defaults to external.
diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_default050.sol b/test/libsolidity/syntaxTests/visibility/interface/function_default050.sol
new file mode 100644
index 00000000..513df26b
--- /dev/null
+++ b/test/libsolidity/syntaxTests/visibility/interface/function_default050.sol
@@ -0,0 +1,7 @@
+pragma experimental "v0.5.0";
+interface I {
+ function f();
+}
+// ----
+// SyntaxError: (45-58): No visibility specified.
+// TypeError: (45-58): Functions in interfaces must be declared external.
diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_external050.sol b/test/libsolidity/syntaxTests/visibility/interface/function_external050.sol
new file mode 100644
index 00000000..3f0a9aca
--- /dev/null
+++ b/test/libsolidity/syntaxTests/visibility/interface/function_external050.sol
@@ -0,0 +1,5 @@
+pragma experimental "v0.5.0";
+interface I {
+ function f() external;
+}
+// ----
diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_internal.sol b/test/libsolidity/syntaxTests/visibility/interface/function_internal.sol
new file mode 100644
index 00000000..ac62e69b
--- /dev/null
+++ b/test/libsolidity/syntaxTests/visibility/interface/function_internal.sol
@@ -0,0 +1,5 @@
+interface I {
+ function f() internal;
+}
+// ----
+// TypeError: (15-37): Functions in interfaces cannot be internal or private.
diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_private.sol b/test/libsolidity/syntaxTests/visibility/interface/function_private.sol
new file mode 100644
index 00000000..881e647e
--- /dev/null
+++ b/test/libsolidity/syntaxTests/visibility/interface/function_private.sol
@@ -0,0 +1,5 @@
+interface I {
+ function f() private;
+}
+// ----
+// TypeError: (15-36): Functions in interfaces cannot be internal or private.
diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_public.sol b/test/libsolidity/syntaxTests/visibility/interface/function_public.sol
new file mode 100644
index 00000000..891d9fdf
--- /dev/null
+++ b/test/libsolidity/syntaxTests/visibility/interface/function_public.sol
@@ -0,0 +1,5 @@
+interface I {
+ function f() public;
+}
+// ----
+// Warning: (15-35): Functions in interfaces should be declared external.
diff --git a/test/libsolidity/syntaxTests/visibility/interface/function_public050.sol b/test/libsolidity/syntaxTests/visibility/interface/function_public050.sol
new file mode 100644
index 00000000..e0c04095
--- /dev/null
+++ b/test/libsolidity/syntaxTests/visibility/interface/function_public050.sol
@@ -0,0 +1,6 @@
+pragma experimental "v0.5.0";
+interface I {
+ function f() public;
+}
+// ----
+// TypeError: (45-65): Functions in interfaces must be declared external.
diff --git a/test/tools/CMakeLists.txt b/test/tools/CMakeLists.txt
new file mode 100644
index 00000000..febb0c26
--- /dev/null
+++ b/test/tools/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_executable(solfuzzer fuzzer.cpp)
+target_link_libraries(solfuzzer PRIVATE libsolc evmasm ${Boost_PROGRAM_OPTIONS_LIBRARIES})
+
+add_executable(isoltest isoltest.cpp ../Options.cpp ../libsolidity/SyntaxTest.cpp ../libsolidity/AnalysisFramework.cpp)
+target_link_libraries(isoltest PRIVATE libsolc solidity evmasm ${Boost_PROGRAM_OPTIONS_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES})
diff --git a/test/fuzzer.cpp b/test/tools/fuzzer.cpp
index 71f38b67..71f38b67 100644
--- a/test/fuzzer.cpp
+++ b/test/tools/fuzzer.cpp
diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp
new file mode 100644
index 00000000..7a147bd0
--- /dev/null
+++ b/test/tools/isoltest.cpp
@@ -0,0 +1,396 @@
+/*
+ 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/>.
+*/
+
+#include <libdevcore/CommonIO.h>
+#include <test/libsolidity/AnalysisFramework.h>
+#include <test/libsolidity/SyntaxTest.h>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/replace.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/program_options.hpp>
+
+#include <cstdlib>
+#include <iostream>
+#include <fstream>
+#include <queue>
+
+using namespace dev;
+using namespace dev::solidity;
+using namespace dev::solidity::test;
+using namespace dev::solidity::test::formatting;
+using namespace std;
+namespace po = boost::program_options;
+namespace fs = boost::filesystem;
+
+struct SyntaxTestStats
+{
+ int successCount;
+ int runCount;
+ operator bool() const { return successCount == runCount; }
+};
+
+class SyntaxTestTool
+{
+public:
+ SyntaxTestTool(string const& _name, fs::path const& _path, bool _formatted):
+ m_formatted(_formatted), m_name(_name), m_path(_path)
+ {}
+
+ enum class Result
+ {
+ Success,
+ Failure,
+ Exception
+ };
+
+ Result process();
+
+ static SyntaxTestStats processPath(
+ fs::path const& _basepath,
+ fs::path const& _path,
+ bool const _formatted
+ );
+
+ static string editor;
+private:
+ enum class Request
+ {
+ Skip,
+ Rerun,
+ Quit
+ };
+
+ Request handleResponse(bool const _exception);
+
+ void printContract() const;
+
+ bool const m_formatted;
+ string const m_name;
+ fs::path const m_path;
+ unique_ptr<SyntaxTest> m_test;
+};
+
+string SyntaxTestTool::editor;
+
+void SyntaxTestTool::printContract() const
+{
+ if (m_formatted)
+ {
+ string const& source = m_test->source();
+ if (source.empty())
+ return;
+
+ std::vector<char const*> sourceFormatting(source.length(), formatting::RESET);
+ for (auto const& error: m_test->errorList())
+ if (error.locationStart >= 0 && error.locationEnd >= 0)
+ {
+ assert(static_cast<size_t>(error.locationStart) < source.length());
+ assert(static_cast<size_t>(error.locationEnd) < source.length());
+ bool isWarning = error.type == "Warning";
+ for (int i = error.locationStart; i < error.locationEnd; i++)
+ if (isWarning)
+ {
+ if (sourceFormatting[i] == formatting::RESET)
+ sourceFormatting[i] = formatting::ORANGE_BACKGROUND;
+ }
+ else
+ sourceFormatting[i] = formatting::RED_BACKGROUND;
+ }
+
+ cout << " " << sourceFormatting.front() << source.front();
+ for (size_t i = 1; i < source.length(); i++)
+ {
+ if (sourceFormatting[i] != sourceFormatting[i - 1])
+ cout << sourceFormatting[i];
+ if (source[i] != '\n')
+ cout << source[i];
+ else
+ {
+ cout << formatting::RESET << endl;
+ if (i + 1 < source.length())
+ cout << " " << sourceFormatting[i];
+ }
+ }
+ cout << formatting::RESET << endl;
+ }
+ else
+ {
+ stringstream stream(m_test->source());
+ string line;
+ while (getline(stream, line))
+ cout << " " << line << endl;
+ cout << endl;
+ }
+}
+
+SyntaxTestTool::Result SyntaxTestTool::process()
+{
+ bool success;
+ std::stringstream outputMessages;
+
+ (FormattedScope(cout, m_formatted, {BOLD}) << m_name << ": ").flush();
+
+ try
+ {
+ m_test = unique_ptr<SyntaxTest>(new SyntaxTest(m_path.string()));
+ success = m_test->run(outputMessages, " ", m_formatted);
+ }
+ catch(CompilerError const& _e)
+ {
+ FormattedScope(cout, m_formatted, {BOLD, RED}) <<
+ "Exception: " << SyntaxTest::errorMessage(_e) << endl;
+ return Result::Exception;
+ }
+ catch(InternalCompilerError const& _e)
+ {
+ FormattedScope(cout, m_formatted, {BOLD, RED}) <<
+ "InternalCompilerError: " << SyntaxTest::errorMessage(_e) << endl;
+ return Result::Exception;
+ }
+ catch(FatalError const& _e)
+ {
+ FormattedScope(cout, m_formatted, {BOLD, RED}) <<
+ "FatalError: " << SyntaxTest::errorMessage(_e) << endl;
+ return Result::Exception;
+ }
+ catch(UnimplementedFeatureError const& _e)
+ {
+ FormattedScope(cout, m_formatted, {BOLD, RED}) <<
+ "UnimplementedFeatureError: " << SyntaxTest::errorMessage(_e) << endl;
+ return Result::Exception;
+ }
+ catch (std::exception const& _e)
+ {
+ FormattedScope(cout, m_formatted, {BOLD, RED}) << "Exception: " << _e.what() << endl;
+ return Result::Exception;
+ }
+ catch(...)
+ {
+ FormattedScope(cout, m_formatted, {BOLD, RED}) <<
+ "Unknown Exception" << endl;
+ return Result::Exception;
+ }
+
+ if (success)
+ {
+ FormattedScope(cout, m_formatted, {BOLD, GREEN}) << "OK" << endl;
+ return Result::Success;
+ }
+ else
+ {
+ FormattedScope(cout, m_formatted, {BOLD, RED}) << "FAIL" << endl;
+
+ FormattedScope(cout, m_formatted, {BOLD, CYAN}) << " Contract:" << endl;
+ printContract();
+
+ cout << outputMessages.str() << endl;
+ return Result::Failure;
+ }
+}
+
+SyntaxTestTool::Request SyntaxTestTool::handleResponse(bool const _exception)
+{
+ if (_exception)
+ cout << "(e)dit/(s)kip/(q)uit? ";
+ else
+ cout << "(e)dit/(u)pdate expectations/(s)kip/(q)uit? ";
+ cout.flush();
+
+ while (true)
+ {
+ switch(readStandardInputChar())
+ {
+ case 's':
+ cout << endl;
+ return Request::Skip;
+ case 'u':
+ if (_exception)
+ break;
+ else
+ {
+ cout << endl;
+ ofstream file(m_path.string(), ios::trunc);
+ file << m_test->source();
+ file << "// ----" << endl;
+ if (!m_test->errorList().empty())
+ m_test->printErrorList(file, m_test->errorList(), "// ", false);
+ return Request::Rerun;
+ }
+ case 'e':
+ cout << endl << endl;
+ if (system((editor + " \"" + m_path.string() + "\"").c_str()))
+ cerr << "Error running editor command." << endl << endl;
+ return Request::Rerun;
+ case 'q':
+ cout << endl;
+ return Request::Quit;
+ default:
+ break;
+ }
+ }
+}
+
+
+SyntaxTestStats SyntaxTestTool::processPath(
+ fs::path const& _basepath,
+ fs::path const& _path,
+ bool const _formatted
+)
+{
+ std::queue<fs::path> paths;
+ paths.push(_path);
+ int successCount = 0;
+ int runCount = 0;
+
+ while (!paths.empty())
+ {
+ auto currentPath = paths.front();
+
+ fs::path fullpath = _basepath / currentPath;
+ if (fs::is_directory(fullpath))
+ {
+ paths.pop();
+ for (auto const& entry: boost::iterator_range<fs::directory_iterator>(
+ fs::directory_iterator(fullpath),
+ fs::directory_iterator()
+ ))
+ if (fs::is_directory(entry.path()) || SyntaxTest::isTestFilename(entry.path().filename()))
+ paths.push(currentPath / entry.path().filename());
+ }
+ else
+ {
+ SyntaxTestTool testTool(currentPath.string(), fullpath, _formatted);
+ ++runCount;
+ auto result = testTool.process();
+
+ switch(result)
+ {
+ case Result::Failure:
+ case Result::Exception:
+ switch(testTool.handleResponse(result == Result::Exception))
+ {
+ case Request::Quit:
+ return { successCount, runCount };
+ case Request::Rerun:
+ cout << "Re-running test case..." << endl;
+ --runCount;
+ break;
+ case Request::Skip:
+ paths.pop();
+ break;
+ }
+ break;
+ case Result::Success:
+ paths.pop();
+ ++successCount;
+ break;
+ }
+ }
+ }
+
+ return { successCount, runCount };
+
+}
+
+int main(int argc, char *argv[])
+{
+ if (getenv("EDITOR"))
+ SyntaxTestTool::editor = getenv("EDITOR");
+ else if (fs::exists("/usr/bin/editor"))
+ SyntaxTestTool::editor = "/usr/bin/editor";
+
+ fs::path testPath;
+ bool formatted = true;
+ po::options_description options(
+ R"(isoltest, tool for interactively managing test contracts.
+Usage: isoltest [Options] --testpath path
+Interactively validates test contracts.
+
+Allowed options)",
+ po::options_description::m_default_line_length,
+ po::options_description::m_default_line_length - 23);
+ options.add_options()
+ ("help", "Show this help screen.")
+ ("testpath", po::value<fs::path>(&testPath), "path to test files")
+ ("no-color", "don't use colors")
+ ("editor", po::value<string>(&SyntaxTestTool::editor), "editor for opening contracts");
+
+ po::variables_map arguments;
+ try
+ {
+ po::command_line_parser cmdLineParser(argc, argv);
+ cmdLineParser.options(options);
+ po::store(cmdLineParser.run(), arguments);
+
+ if (arguments.count("help"))
+ {
+ cout << options << endl;
+ return 0;
+ }
+
+ if (arguments.count("no-color"))
+ formatted = false;
+
+ po::notify(arguments);
+ }
+ catch (po::error const& _exception)
+ {
+ cerr << _exception.what() << endl;
+ return 1;
+ }
+
+ if (testPath.empty())
+ {
+ auto const searchPath =
+ {
+ fs::current_path() / ".." / ".." / ".." / "test",
+ fs::current_path() / ".." / ".." / "test",
+ fs::current_path() / ".." / "test",
+ fs::current_path() / "test",
+ fs::current_path()
+ };
+ for (auto const& basePath : searchPath)
+ {
+ fs::path syntaxTestPath = basePath / "libsolidity" / "syntaxTests";
+ if (fs::exists(syntaxTestPath) && fs::is_directory(syntaxTestPath))
+ {
+ testPath = basePath;
+ break;
+ }
+ }
+ }
+
+ fs::path syntaxTestPath = testPath / "libsolidity" / "syntaxTests";
+
+ if (fs::exists(syntaxTestPath) && fs::is_directory(syntaxTestPath))
+ {
+ auto stats = SyntaxTestTool::processPath(testPath / "libsolidity", "syntaxTests", formatted);
+
+ cout << endl << "Summary: ";
+ FormattedScope(cout, formatted, {BOLD, stats ? GREEN : RED}) <<
+ stats.successCount << "/" << stats.runCount;
+ cout << " tests successful." << endl;
+
+ return stats ? 0 : 1;
+ }
+ else
+ {
+ cerr << "Test path not found. Use the --testpath argument." << endl;
+ return 1;
+ }
+}