diff options
28 files changed, 206 insertions, 30 deletions
diff --git a/Changelog.md b/Changelog.md index 5cd4c2f8..70e98751 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,19 +1,24 @@ ### 0.4.22 (unreleased) Features: + * Commandline interface: Error when missing or inaccessible file detected. Suppress it with the ``--ignore-missing`` flag. * General: Support accessing dynamic return data in post-byzantium EVMs. * Interfaces: Allow overriding external functions in interfaces with public in an implementing contract. + * Syntax Checker: Issue warning for empty structs (or error as experimental 0.5.0 feature). Bugfixes: * Code Generator: Allow ``block.blockhash`` without being called. * Code Generator: Do not include internal functions in the runtime bytecode which are only referenced in the constructor. * Code Generator: Properly skip unneeded storage array cleanup when not reducing length. * Code Generator: Bugfix in modifier lookup in libraries. + * Code Generator: Implement packed encoding of external function types. + * Code Generator: Treat empty base constructor argument list as not provided. * Commandline interface: Support ``--evm-version constantinople`` properly. * DocString Parser: Fix error message for empty descriptions. * Standard JSON: Support ``constantinople`` as ``evmVersion`` properly. * Type System: Improve error message when attempting to shift by a fractional amount. * Type System: Make external library functions accessible. + * Type System: Prevent encoding of weird types. ### 0.4.21 (2018-03-07) diff --git a/docs/abi-spec.rst b/docs/abi-spec.rst index 4d84a7da..98301fdc 100644 --- a/docs/abi-spec.rst +++ b/docs/abi-spec.rst @@ -54,7 +54,7 @@ The following elementary types exist: - ``ufixed<M>x<N>``: unsigned variant of ``fixed<M>x<N>``. -- ``fixed``, ``ufixed``: synonyms for ``fixed128x19``, ``ufixed128x19`` respectively. For computing the function selector, ``fixed128x19`` and ``ufixed128x19`` have to be used. +- ``fixed``, ``ufixed``: synonyms for ``fixed128x18``, ``ufixed128x18`` respectively. For computing the function selector, ``fixed128x18`` and ``ufixed128x18`` have to be used. - ``bytes<M>``: binary type of ``M`` bytes, ``0 < M <= 32``. @@ -164,9 +164,9 @@ on the type of ``X`` being - ``int<M>``: ``enc(X)`` is the big-endian two's complement encoding of ``X``, padded on the higher-order (left) side with ``0xff`` for negative ``X`` and with zero bytes for positive ``X`` such that the length is 32 bytes. - ``bool``: as in the ``uint8`` case, where ``1`` is used for ``true`` and ``0`` for ``false`` - ``fixed<M>x<N>``: ``enc(X)`` is ``enc(X * 10**N)`` where ``X * 10**N`` is interpreted as a ``int256``. -- ``fixed``: as in the ``fixed128x19`` case +- ``fixed``: as in the ``fixed128x18`` case - ``ufixed<M>x<N>``: ``enc(X)`` is ``enc(X * 10**N)`` where ``X * 10**N`` is interpreted as a ``uint256``. -- ``ufixed``: as in the ``ufixed128x19`` case +- ``ufixed``: as in the ``ufixed128x18`` case - ``bytes<M>``: ``enc(X)`` is the sequence of bytes in ``X`` padded with trailing zero-bytes to a length of 32 bytes. Note that for any ``X``, ``len(enc(X))`` is a multiple of 32. diff --git a/docs/contracts.rst b/docs/contracts.rst index 121c4de0..8cc4f6b2 100644 --- a/docs/contracts.rst +++ b/docs/contracts.rst @@ -679,7 +679,7 @@ candidate, resolution fails. } } -Calling ``f(50)`` would create a type error since ``250`` can be implicitly converted both to ``uint8`` +Calling ``f(50)`` would create a type error since ``50`` can be implicitly converted both to ``uint8`` and ``uint256`` types. On another hand ``f(256)`` would resolve to ``f(uint256)`` overload as ``256`` cannot be implicitly converted to ``uint8``. diff --git a/docs/grammar.txt b/docs/grammar.txt index a5c2acf3..b4ca5ca9 100644 --- a/docs/grammar.txt +++ b/docs/grammar.txt @@ -19,7 +19,7 @@ InheritanceSpecifier = UserDefinedTypeName ( '(' Expression ( ',' Expression )* StateVariableDeclaration = TypeName ( 'public' | 'internal' | 'private' | 'constant' )? Identifier ('=' Expression)? ';' UsingForDeclaration = 'using' Identifier 'for' ('*' | TypeName) ';' StructDefinition = 'struct' Identifier '{' - ( VariableDeclaration ';' (VariableDeclaration ';')* )? '}' + ( VariableDeclaration ';' (VariableDeclaration ';')* ) '}' ModifierDefinition = 'modifier' Identifier ParameterList? Block ModifierInvocation = Identifier ( '(' ExpressionList? ')' )? diff --git a/docs/installing-solidity.rst b/docs/installing-solidity.rst index e26870f0..6726ded9 100644 --- a/docs/installing-solidity.rst +++ b/docs/installing-solidity.rst @@ -122,7 +122,6 @@ We will re-add the pre-built bottles soon. brew upgrade brew tap ethereum/ethereum brew install solidity - brew linkapps solidity If you need a specific version of Solidity you can install a Homebrew formula directly from Github. diff --git a/docs/style-guide.rst b/docs/style-guide.rst index 2261746f..ee1ea4bd 100644 --- a/docs/style-guide.rst +++ b/docs/style-guide.rst @@ -904,7 +904,7 @@ Constants ========= Constants should be named with all capital letters with underscores separating -words. Examples: ``MAX_BLOCKS``, `TOKEN_NAME`, ``TOKEN_TICKER``, ``CONTRACT_VERSION``. +words. Examples: ``MAX_BLOCKS``, ``TOKEN_NAME``, ``TOKEN_TICKER``, ``CONTRACT_VERSION``. Modifier Names diff --git a/docs/types.rst b/docs/types.rst index e704687e..5de6d07e 100644 --- a/docs/types.rst +++ b/docs/types.rst @@ -81,7 +81,7 @@ Fixed Point Numbers ``fixed`` / ``ufixed``: Signed and unsigned fixed point number of various sizes. Keywords ``ufixedMxN`` and ``fixedMxN``, where ``M`` represents the number of bits taken by the type and ``N`` represents how many decimal points are available. ``M`` must be divisible by 8 and goes from 8 to 256 bits. ``N`` must be between 0 and 80, inclusive. -``ufixed`` and ``fixed`` are aliases for ``ufixed128x19`` and ``fixed128x19``, respectively. +``ufixed`` and ``fixed`` are aliases for ``ufixed128x18`` and ``fixed128x18``, respectively. Operators: diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp index 5de9a270..b595c4d1 100644 --- a/libsolidity/analysis/SyntaxChecker.cpp +++ b/libsolidity/analysis/SyntaxChecker.cpp @@ -246,3 +246,17 @@ bool SyntaxChecker::visit(VariableDeclaration const& _declaration) } return true; } + +bool SyntaxChecker::visit(StructDefinition const& _struct) +{ + bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050); + + if (_struct.members().empty()) + { + if (v050) + m_errorReporter.syntaxError(_struct.location(), "Defining empty structs is disallowed."); + else + m_errorReporter.warning(_struct.location(), "Defining empty structs is deprecated."); + } + return true; +} diff --git a/libsolidity/analysis/SyntaxChecker.h b/libsolidity/analysis/SyntaxChecker.h index 871bf0a9..1579df57 100644 --- a/libsolidity/analysis/SyntaxChecker.h +++ b/libsolidity/analysis/SyntaxChecker.h @@ -71,6 +71,8 @@ private: virtual bool visit(VariableDeclaration const& _declaration) override; + virtual bool visit(StructDefinition const& _struct) override; + ErrorReporter& m_errorReporter; /// Flag that indicates whether a function modifier actually contains '_'. diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 6e287f83..620dfca4 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1644,9 +1644,20 @@ bool TypeChecker::visit(FunctionCall const& _functionCall) auto const& argType = type(*arguments[i]); if (functionType->takesArbitraryParameters()) { + bool errored = false; if (auto t = dynamic_cast<RationalNumberType const*>(argType.get())) if (!t->mobileType()) + { m_errorReporter.typeError(arguments[i]->location(), "Invalid rational number (too large or division by zero)."); + errored = true; + } + if (!errored && !( + argType->mobileType() && + argType->mobileType()->interfaceType(false) && + argType->mobileType()->interfaceType(false)->encodingType() && + !(dynamic_cast<StructType const*>(argType->mobileType()->interfaceType(false)->encodingType().get())) + )) + m_errorReporter.typeError(arguments[i]->location(), "This type cannot be encoded."); } else if (!type(*arguments[i])->isImplicitlyConvertibleTo(*parameterTypes[i])) m_errorReporter.typeError( diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 720215c9..42fd1c3d 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -208,9 +208,9 @@ TypePointer Type::fromElementaryTypeName(ElementaryTypeNameToken const& _type) case Token::UInt: return make_shared<IntegerType>(256, IntegerType::Modifier::Unsigned); case Token::Fixed: - return make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Signed); + return make_shared<FixedPointType>(128, 18, FixedPointType::Modifier::Signed); case Token::UFixed: - return make_shared<FixedPointType>(128, 19, FixedPointType::Modifier::Unsigned); + return make_shared<FixedPointType>(128, 18, FixedPointType::Modifier::Unsigned); case Token::Byte: return make_shared<FixedBytesType>(1); case Token::Address: @@ -1262,6 +1262,8 @@ bool ContractType::isPayable() const TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const { + if (isSuper()) + return TypePointer{}; return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer(); } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index c930dd24..b7e64891 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -692,22 +692,27 @@ public: virtual bool operator==(Type const& _other) const override; virtual unsigned calldataEncodedSize(bool _padded ) const override { + solAssert(!isSuper(), ""); return encodingType()->calldataEncodedSize(_padded); } - virtual unsigned storageBytes() const override { return 20; } - virtual bool canLiveOutsideStorage() const override { return true; } + virtual unsigned storageBytes() const override { solAssert(!isSuper(), ""); return 20; } + virtual bool canLiveOutsideStorage() const override { return !isSuper(); } virtual unsigned sizeOnStack() const override { return m_super ? 0 : 1; } - virtual bool isValueType() const override { return true; } + virtual bool isValueType() const override { return !isSuper(); } virtual std::string toString(bool _short) const override; virtual std::string canonicalName() const override; virtual MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override; virtual TypePointer encodingType() const override { + if (isSuper()) + return TypePointer{}; return std::make_shared<IntegerType>(160, IntegerType::Modifier::Address); } virtual TypePointer interfaceType(bool _inLibrary) const override { + if (isSuper()) + return TypePointer{}; return _inLibrary ? shared_from_this() : encodingType(); } diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 68f0b3a1..676d5d4e 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -142,7 +142,6 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound dynamic_cast<FunctionType const&>(_type).kind() == FunctionType::Kind::External ) { - solUnimplementedAssert(_padToWordBoundaries, "Non-padded store for function not implemented."); combineExternalFunctionType(true); m_context << Instruction::DUP2 << Instruction::MSTORE; m_context << u256(_padToWordBoundaries ? 32 : 24) << Instruction::ADD; diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 791edc65..ebd9139a 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -143,8 +143,9 @@ void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _c for (auto const& modifier: constructor->modifiers()) { auto baseContract = dynamic_cast<ContractDefinition const*>( - modifier->name()->annotation().referencedDeclaration); - if (baseContract) + modifier->name()->annotation().referencedDeclaration + ); + if (baseContract && !modifier->arguments().empty()) if (m_baseArguments.count(baseContract->constructor()) == 0) m_baseArguments[baseContract->constructor()] = &modifier->arguments(); } @@ -156,7 +157,7 @@ void ContractCompiler::appendInitAndConstructorCode(ContractDefinition const& _c ); solAssert(baseContract, ""); - if (m_baseArguments.count(baseContract->constructor()) == 0) + if (!m_baseArguments.count(baseContract->constructor()) && !base->arguments().empty()) m_baseArguments[baseContract->constructor()] = &base->arguments(); } } @@ -238,6 +239,7 @@ void ContractCompiler::appendBaseConstructor(FunctionDefinition const& _construc solAssert(m_baseArguments.count(&_constructor), ""); std::vector<ASTPointer<Expression>> const* arguments = m_baseArguments[&_constructor]; solAssert(arguments, ""); + solAssert(arguments->size() == constructorType.parameterTypes().size(), ""); for (unsigned i = 0; i < arguments->size(); ++i) compileExpression(*(arguments->at(i)), constructorType.parameterTypes()[i]); } diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index d3d234c3..8f81e799 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -116,6 +116,7 @@ static string const g_strStandardJSON = "standard-json"; static string const g_strStrictAssembly = "strict-assembly"; static string const g_strPrettyJson = "pretty-json"; static string const g_strVersion = "version"; +static string const g_strIgnoreMissingFiles = "ignore-missing"; static string const g_argAbi = g_strAbi; static string const g_argPrettyJson = g_strPrettyJson; @@ -152,6 +153,7 @@ static string const g_argStandardJSON = g_strStandardJSON; static string const g_argStrictAssembly = g_strStrictAssembly; static string const g_argVersion = g_strVersion; static string const g_stdinFileName = g_stdinFileNameStr; +static string const g_argIgnoreMissingFiles = g_strIgnoreMissingFiles; /// Possible arguments to for --combined-json static set<string> const g_combinedJsonArgs @@ -398,8 +400,9 @@ void CommandLineInterface::handleGasEstimation(string const& _contract) } } -void CommandLineInterface::readInputFilesAndConfigureRemappings() +bool CommandLineInterface::readInputFilesAndConfigureRemappings() { + bool ignoreMissing = m_args.count(g_argIgnoreMissingFiles); bool addStdin = false; if (!m_args.count(g_argInputFile)) addStdin = true; @@ -416,13 +419,27 @@ void CommandLineInterface::readInputFilesAndConfigureRemappings() auto infile = boost::filesystem::path(path); if (!boost::filesystem::exists(infile)) { - cerr << "Skipping non-existent input file \"" << infile << "\"" << endl; + if (!ignoreMissing) + { + cerr << "\"" << infile << "\" is not found" << endl; + return false; + } + else + cerr << "\"" << infile << "\" is not found. Skipping." << endl; + continue; } if (!boost::filesystem::is_regular_file(infile)) { - cerr << "\"" << infile << "\" is not a valid file. Skipping" << endl; + if (!ignoreMissing) + { + cerr << "\"" << infile << "\" is not a valid file" << endl; + return false; + } + else + cerr << "\"" << infile << "\" is not a valid file. Skipping." << endl; + continue; } @@ -433,6 +450,8 @@ void CommandLineInterface::readInputFilesAndConfigureRemappings() } if (addStdin) m_sourceCodes[g_stdinFileName] = dev::readStandardInput(); + + return true; } bool CommandLineInterface::parseLibraryOption(string const& _input) @@ -599,7 +618,8 @@ Allowed options)", g_argAllowPaths.c_str(), po::value<string>()->value_name("path(s)"), "Allow a given path for imports. A list of paths can be supplied by separating them with a comma." - ); + ) + (g_argIgnoreMissingFiles.c_str(), "Ignore missing files."); po::options_description outputComponents("Output Components"); outputComponents.add_options() (g_argAst.c_str(), "AST of all source files.") @@ -741,7 +761,8 @@ bool CommandLineInterface::processInput() return true; } - readInputFilesAndConfigureRemappings(); + if (!readInputFilesAndConfigureRemappings()) + return false; if (m_args.count(g_argLibraries)) for (string const& library: m_args[g_argLibraries].as<vector<string>>()) diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index 303023fc..45ec1eb5 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -72,7 +72,7 @@ private: void handleFormal(); /// Fills @a m_sourceCodes initially and @a m_redirects. - void readInputFilesAndConfigureRemappings(); + bool readInputFilesAndConfigureRemappings(); /// Tries to read from the file @a _input or interprets _input literally if that fails. /// It then tries to parse the contents and appends to m_libraries. bool parseLibraryOption(std::string const& _input); diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh index 92f9569a..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 diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index a866e46c..f5813aed 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -2077,6 +2077,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"( diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 1e98d50d..dcdc1519 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -2452,8 +2452,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) @@ -4471,7 +4471,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) @@ -4589,7 +4589,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) @@ -4676,7 +4676,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) @@ -7241,7 +7241,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; _; diff --git a/test/libsolidity/syntaxTests/empty_struct.sol b/test/libsolidity/syntaxTests/empty_struct.sol new file mode 100644 index 00000000..dcced618 --- /dev/null +++ b/test/libsolidity/syntaxTests/empty_struct.sol @@ -0,0 +1,5 @@ +contract test { + struct A {} +} +// ---- +// Warning: 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..dbec93c4 --- /dev/null +++ b/test/libsolidity/syntaxTests/empty_struct_050.sol @@ -0,0 +1,6 @@ +pragma experimental "v0.5.0"; +contract test { + struct A {} +} +// ---- +// SyntaxError: Defining empty structs is disallowed. 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..76df0657 --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/base_arguments_empty_parentheses.sol @@ -0,0 +1,6 @@ +contract Base { + function Base(uint) public {} +} +contract Derived is Base(2) { } +contract Derived2 is Base(), Derived() { } +contract Derived3 is Base, Derived {} 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..82aba308 --- /dev/null +++ b/test/libsolidity/syntaxTests/inheritance/too_few_base_arguments.sol @@ -0,0 +1,10 @@ +contract Base { + function Base(uint, uint) public {} +} +contract Derived is Base(2) { } +contract Derived2 is Base { + function Derived2() Base(2) public { } +} +// ---- +// TypeError: Wrong argument count for constructor call: 1 arguments given but expected 2. +// TypeError: Wrong argument count for modifier invocation: 1 arguments given but expected 2. 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..9f57c3a4 --- /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: This type cannot be encoded. +// TypeError: This type cannot be encoded. +// TypeError: This type cannot be encoded. +// TypeError: 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..a7d13215 --- /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: This type cannot be encoded. +// TypeError: This type cannot be encoded. +// TypeError: This type cannot be encoded. +// TypeError: This type cannot be encoded. +// TypeError: 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..378155e9 --- /dev/null +++ b/test/libsolidity/syntaxTests/specialFunctions/types_with_unspecified_encoding_structs.sol @@ -0,0 +1,14 @@ +contract C { + struct S { uint x; } + S s; + struct T { } + T t; + function f() public pure { + bytes32 a = sha256(s, t); + a; + } +} +// ---- +// Warning: Defining empty structs is deprecated. +// TypeError: This type cannot be encoded. +// TypeError: 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..6e073fd8 --- /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: Defining empty structs is deprecated. +// TypeError: This type cannot be encoded. +// TypeError: This type cannot be encoded. +// TypeError: This type cannot be encoded. +// TypeError: This type cannot be encoded. +// TypeError: 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; + } +} +// ---- |