From 98e5923e3aa5d4606de0ddc71916993478c5f9ae Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 22 Jun 2020 18:10:18 +0200 Subject: [PATCH 1/4] Do now disallow assigning to external parameters. --- Changelog.md | 1 + libsolidity/ast/AST.cpp | 7 +------ .../syntaxTests/lvalues/external_reference_argument.sol | 1 - .../libsolidity/syntaxTests/structs/memory_to_calldata.sol | 2 -- 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/Changelog.md b/Changelog.md index 843d47ba5..91a7fc43f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,7 @@ Compiler Features: Bugfixes: * NatSpec: Do not consider ``////`` and ``/***`` as NatSpec comments. * Type Checker: Fix internal error related to ``using for`` applied to non-libraries. + * Type Checker: Do not disallow assigning to calldata variables. * Yul: Fix source location of variable multi-assignment. diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 3492bfc45..f3f79f451 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -492,12 +492,7 @@ DeclarationAnnotation& Declaration::annotation() const bool VariableDeclaration::isLValue() const { // Constant declared variables are Read-Only - if (isConstant()) - return false; - // External function arguments of reference type are Read-Only - if (isExternalCallableParameter() && dynamic_cast(type())) - return false; - return true; + return !isConstant(); } bool VariableDeclaration::isLocalVariable() const diff --git a/test/libsolidity/syntaxTests/lvalues/external_reference_argument.sol b/test/libsolidity/syntaxTests/lvalues/external_reference_argument.sol index ed638781c..67378653b 100644 --- a/test/libsolidity/syntaxTests/lvalues/external_reference_argument.sol +++ b/test/libsolidity/syntaxTests/lvalues/external_reference_argument.sol @@ -4,4 +4,3 @@ contract C { } } // ---- -// TypeError 7128: (96-97): External function arguments of reference type are read-only. diff --git a/test/libsolidity/syntaxTests/structs/memory_to_calldata.sol b/test/libsolidity/syntaxTests/structs/memory_to_calldata.sol index d6b2aed6a..19747e9a5 100644 --- a/test/libsolidity/syntaxTests/structs/memory_to_calldata.sol +++ b/test/libsolidity/syntaxTests/structs/memory_to_calldata.sol @@ -5,7 +5,5 @@ contract Test { function g(S calldata s) external { S memory m; s = m; } } // ---- -// TypeError 7128: (114-115): External function arguments of reference type are read-only. // TypeError 7407: (118-122): Type struct Test.S memory is not implicitly convertible to expected type struct Test.S calldata. -// TypeError 7128: (178-179): External function arguments of reference type are read-only. // TypeError 7407: (182-183): Type struct Test.S memory is not implicitly convertible to expected type struct Test.S calldata. From 25ebff3a38e1b82c939a0f8fa4e940f335c9b2ba Mon Sep 17 00:00:00 2001 From: a3d4 Date: Wed, 17 Jun 2020 04:58:15 +0200 Subject: [PATCH 2/4] Fix pragma solidity version in antlr grammar --- docs/Solidity.g4 | 17 +---------------- .../syntaxTests/pragma/version_check.sol | 7 +++++++ 2 files changed, 8 insertions(+), 16 deletions(-) create mode 100644 test/libsolidity/syntaxTests/pragma/version_check.sol diff --git a/docs/Solidity.g4 b/docs/Solidity.g4 index fdc80822b..65fee05fa 100644 --- a/docs/Solidity.g4 +++ b/docs/Solidity.g4 @@ -11,23 +11,11 @@ sourceUnit : (pragmaDirective | importDirective | structDefinition | enumDefinition | contractDefinition)* EOF ; pragmaDirective - : 'pragma' pragmaName pragmaValue ';' ; + : 'pragma' pragmaName ( ~';' )* ';' ; pragmaName : identifier ; -pragmaValue - : version | expression ; - -version - : versionConstraint versionConstraint? ; - -versionConstraint - : versionOperator? VersionLiteral ; - -versionOperator - : '^' | '~' | '>=' | '>' | '<' | '<=' | '=' ; - importDirective : 'import' StringLiteralFragment ('as' identifier)? ';' | 'import' ('*' | identifier) ('as' identifier)? 'from' StringLiteralFragment ';' @@ -473,9 +461,6 @@ fragment SingleQuotedStringCharacter : ~['\r\n\\] | ('\\' .) ; -VersionLiteral - : [0-9]+ ( '.' [0-9]+ ('.' [0-9]+)? )? ; - WS : [ \t\r\n\u000C]+ -> skip ; diff --git a/test/libsolidity/syntaxTests/pragma/version_check.sol b/test/libsolidity/syntaxTests/pragma/version_check.sol new file mode 100644 index 000000000..45b98d9ee --- /dev/null +++ b/test/libsolidity/syntaxTests/pragma/version_check.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity < 142857; +pragma solidity >= 0.0; +pragma solidity >= 0.0.0; + +contract C { +} From 86be0fbc2fa242bc56302984675b3bec4b18fc07 Mon Sep 17 00:00:00 2001 From: Alexander Arlt Date: Tue, 16 Jun 2020 21:23:26 -0500 Subject: [PATCH 3/4] [ewasm] Fix infinite loops. --- Changelog.md | 1 + libyul/backends/wasm/WasmCodeTransform.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index 91a7fc43f..9328f2824 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Bugfixes: * NatSpec: Do not consider ``////`` and ``/***`` as NatSpec comments. * Type Checker: Fix internal error related to ``using for`` applied to non-libraries. * Type Checker: Do not disallow assigning to calldata variables. + * Wasm backend: Fix code generation for for-loops with pre statements. * Yul: Fix source location of variable multi-assignment. diff --git a/libyul/backends/wasm/WasmCodeTransform.cpp b/libyul/backends/wasm/WasmCodeTransform.cpp index d2bceaa90..5171db1b1 100644 --- a/libyul/backends/wasm/WasmCodeTransform.cpp +++ b/libyul/backends/wasm/WasmCodeTransform.cpp @@ -257,9 +257,10 @@ wasm::Expression WasmCodeTransform::operator()(ForLoop const& _for) YulString eqz_instruction = YulString(conditionType.str() + ".eqz"); yulAssert(WasmDialect::instance().builtin(eqz_instruction), ""); + std::vector statements = visit(_for.pre.statements); + wasm::Loop loop; loop.labelName = newLabel(); - loop.statements = visit(_for.pre.statements); loop.statements.emplace_back(wasm::BranchIf{wasm::Label{breakLabel}, make_unique( wasm::BuiltinCall{eqz_instruction.str(), make_vector( visitReturnByValue(*_for.condition) @@ -269,7 +270,8 @@ wasm::Expression WasmCodeTransform::operator()(ForLoop const& _for) loop.statements += visit(_for.post.statements); loop.statements.emplace_back(wasm::Branch{wasm::Label{loop.labelName}}); - return { wasm::Block{breakLabel, make_vector(move(loop))} }; + statements += make_vector(move(loop)); + return wasm::Block{breakLabel, move(statements)}; } wasm::Expression WasmCodeTransform::operator()(Break const&) From 0397266351e90531fe67f69d69253265d55d321a Mon Sep 17 00:00:00 2001 From: Bhargava Shastry Date: Thu, 18 Jun 2020 12:31:55 +0200 Subject: [PATCH 4/4] Implement multi source semantic tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: chriseth Co-authored-by: Kamil ƚliwak --- test/CommonSyntaxTest.cpp | 15 +++--- test/ExecutionFramework.h | 19 ++++--- test/TestCaseReader.cpp | 11 ++-- test/TestCaseReader.h | 22 +++++--- test/libsolidity/ABIEncoderTests.cpp | 2 +- test/libsolidity/SemanticTest.cpp | 53 +++++++++++++++---- test/libsolidity/SemanticTest.h | 3 +- test/libsolidity/SolidityEndToEndTest.cpp | 4 +- .../SolidityExecutionFramework.cpp | 43 +++++++++++---- test/libsolidity/SolidityExecutionFramework.h | 21 +++++--- .../semanticTests/multiSource/import.sol | 12 +++++ test/tools/isoltest.cpp | 4 -- 12 files changed, 146 insertions(+), 63 deletions(-) create mode 100644 test/libsolidity/semanticTests/multiSource/import.sol diff --git a/test/CommonSyntaxTest.cpp b/test/CommonSyntaxTest.cpp index 98a74cb86..ff99d6e24 100644 --- a/test/CommonSyntaxTest.cpp +++ b/test/CommonSyntaxTest.cpp @@ -58,10 +58,10 @@ int parseUnsignedInteger(string::iterator& _it, string::iterator _end) CommonSyntaxTest::CommonSyntaxTest(string const& _filename, langutil::EVMVersion _evmVersion): EVMVersionRestrictedTestCase(_filename), + m_sources(m_reader.sources().sources), + m_expectations(parseExpectations(m_reader.stream())), m_evmVersion(_evmVersion) { - m_sources = m_reader.sources(); - m_expectations = parseExpectations(m_reader.stream()); } TestCase::TestResult CommonSyntaxTest::run(ostream& _stream, string const& _linePrefix, bool _formatted) @@ -94,12 +94,10 @@ void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix, if (m_sources.empty()) return; - bool outputSourceNames = true; - if (m_sources.size() == 1 && m_sources.begin()->first.empty()) - outputSourceNames = false; + bool outputSourceNames = (m_sources.size() != 1 || !m_sources.begin()->first.empty()); - if (_formatted) - for (auto const& [name, source]: m_sources) + for (auto const& [name, source]: m_sources) + if (_formatted) { if (source.empty()) continue; @@ -139,8 +137,7 @@ void CommonSyntaxTest::printSource(ostream& _stream, string const& _linePrefix, } _stream << formatting::RESET; } - else - for (auto const& [name, source]: m_sources) + else { if (outputSourceNames) _stream << _linePrefix << "==== Source: " + name << " ====" << endl; diff --git a/test/ExecutionFramework.h b/test/ExecutionFramework.h index e55a12aa6..72a07ce3e 100644 --- a/test/ExecutionFramework.h +++ b/test/ExecutionFramework.h @@ -61,22 +61,28 @@ public: virtual ~ExecutionFramework() = default; virtual bytes const& compileAndRunWithoutCheck( - std::string const& _sourceCode, + std::map const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "", - bytes const& _arguments = bytes(), - std::map const& _libraryAddresses = std::map() + bytes const& _arguments = {}, + std::map const& _libraryAddresses = {} ) = 0; bytes const& compileAndRun( std::string const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "", - bytes const& _arguments = bytes(), - std::map const& _libraryAddresses = std::map() + bytes const& _arguments = {}, + std::map const& _libraryAddresses = {} ) { - compileAndRunWithoutCheck(_sourceCode, _value, _contractName, _arguments, _libraryAddresses); + compileAndRunWithoutCheck( + {{"", _sourceCode}}, + _value, + _contractName, + _arguments, + _libraryAddresses + ); BOOST_REQUIRE(m_transactionSuccessful); BOOST_REQUIRE(!m_output.empty()); return m_output; @@ -293,4 +299,3 @@ protected: } // end namespaces - diff --git a/test/TestCaseReader.cpp b/test/TestCaseReader.cpp index 0f49a6401..2f90678ed 100644 --- a/test/TestCaseReader.cpp +++ b/test/TestCaseReader.cpp @@ -37,11 +37,11 @@ TestCaseReader::TestCaseReader(string const& _filename): m_unreadSettings = m_settings; } -string const& TestCaseReader::source() +string const& TestCaseReader::source() const { - if (m_sources.size() != 1) + if (m_sources.sources.size() != 1) BOOST_THROW_EXCEPTION(runtime_error("Expected single source definition, but got multiple sources.")); - return m_sources.begin()->second; + return m_sources.sources.at(m_sources.mainSourceFile); } string TestCaseReader::simpleExpectations() @@ -93,7 +93,7 @@ void TestCaseReader::ensureAllSettingsRead() const ); } -pair, size_t> TestCaseReader::parseSourcesAndSettingsWithLineNumber(istream& _stream) +pair TestCaseReader::parseSourcesAndSettingsWithLineNumber(istream& _stream) { map sources; string currentSourceName; @@ -145,8 +145,9 @@ pair, size_t> TestCaseReader::parseSourcesAndSettingsWithLin else throw runtime_error(string("Expected \"//\" or \"// ---\" to terminate settings and source.")); } + // Register the last source as the main one sources[currentSourceName] = currentSource; - return { sources, lineNumber }; + return {{move(sources), move(currentSourceName)}, lineNumber}; } string TestCaseReader::parseSimpleExpectations(istream& _file) diff --git a/test/TestCaseReader.h b/test/TestCaseReader.h index 5ab226826..9f94f898d 100644 --- a/test/TestCaseReader.h +++ b/test/TestCaseReader.h @@ -23,6 +23,16 @@ namespace solidity::frontend::test { + +/** + * A map for registering source names that also contains the main source name in a test case. + */ +struct SourceMap +{ + std::map sources; + std::string mainSourceFile; +}; + /** * A reader for test case data file, which parses source, settings and (optionally) simple expectations. */ @@ -32,10 +42,10 @@ public: TestCaseReader() = default; explicit TestCaseReader(std::string const& _filename); - std::map const& sources() { return m_sources; } - std::string const& source(); - std::size_t lineNumber() { return m_lineNumber; } - std::map const& settings() { return m_settings; } + SourceMap const& sources() const { return m_sources; } + std::string const& source() const; + std::size_t lineNumber() const { return m_lineNumber; } + std::map const& settings() const { return m_settings; } std::ifstream& stream() { return m_file; } std::string simpleExpectations(); @@ -47,11 +57,11 @@ public: void ensureAllSettingsRead() const; private: - std::pair, std::size_t> parseSourcesAndSettingsWithLineNumber(std::istream& _file); + std::pair parseSourcesAndSettingsWithLineNumber(std::istream& _file); static std::string parseSimpleExpectations(std::istream& _file); std::ifstream m_file; - std::map m_sources; + SourceMap m_sources; std::size_t m_lineNumber = 0; std::map m_settings; std::map m_unreadSettings; ///< tracks which settings are left unread diff --git a/test/libsolidity/ABIEncoderTests.cpp b/test/libsolidity/ABIEncoderTests.cpp index 2e50fe743..777f991a3 100644 --- a/test/libsolidity/ABIEncoderTests.cpp +++ b/test/libsolidity/ABIEncoderTests.cpp @@ -777,7 +777,7 @@ BOOST_AUTO_TEST_CASE(struct_in_constructor_data_short) NEW_ENCODER( BOOST_CHECK( - compileAndRunWithoutCheck(sourceCode, 0, "C", encodeArgs(0x20, 0x60, 0x03, 0x80, 0x00)).empty() + compileAndRunWithoutCheck({{"", sourceCode}}, 0, "C", encodeArgs(0x20, 0x60, 0x03, 0x80, 0x00)).empty() ); ) } diff --git a/test/libsolidity/SemanticTest.cpp b/test/libsolidity/SemanticTest.cpp index 39744fa59..e3b40f1e4 100644 --- a/test/libsolidity/SemanticTest.cpp +++ b/test/libsolidity/SemanticTest.cpp @@ -42,11 +42,10 @@ namespace fs = boost::filesystem; SemanticTest::SemanticTest(string const& _filename, langutil::EVMVersion _evmVersion, bool enforceViaYul): SolidityExecutionFramework(_evmVersion), EVMVersionRestrictedTestCase(_filename), + m_sources(m_reader.sources()), + m_lineOffset(m_reader.lineNumber()), m_enforceViaYul(enforceViaYul) { - m_source = m_reader.source(); - m_lineOffset = m_reader.lineNumber(); - string choice = m_reader.stringSetting("compileViaYul", "false"); if (choice == "also") { @@ -239,12 +238,48 @@ TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePref return TestResult::Success; } -void SemanticTest::printSource(ostream& _stream, string const& _linePrefix, bool) const +void SemanticTest::printSource(ostream& _stream, string const& _linePrefix, bool _formatted) const { - stringstream stream(m_source); - string line; - while (getline(stream, line)) - _stream << _linePrefix << line << endl; + if (m_sources.sources.empty()) + return; + + bool outputNames = (m_sources.sources.size() != 1 || !m_sources.sources.begin()->first.empty()); + + for (auto const& [name, source]: m_sources.sources) + if (_formatted) + { + if (source.empty()) + continue; + + if (outputNames) + _stream << _linePrefix << formatting::CYAN << "==== Source: " << name << " ====" << formatting::RESET << endl; + vector sourceFormatting(source.length(), formatting::RESET); + + _stream << _linePrefix << sourceFormatting.front() << source.front(); + for (size_t i = 1; i < source.length(); i++) + { + if (sourceFormatting[i] != sourceFormatting[i - 1]) + _stream << sourceFormatting[i]; + if (source[i] != '\n') + _stream << source[i]; + else + { + _stream << formatting::RESET << endl; + if (i + 1 < source.length()) + _stream << _linePrefix << sourceFormatting[i]; + } + } + _stream << formatting::RESET; + } + else + { + if (outputNames) + _stream << _linePrefix << "==== Source: " + name << " ====" << endl; + stringstream stream(source); + string line; + while (getline(stream, line)) + _stream << _linePrefix << line << endl; + } } void SemanticTest::printUpdatedExpectations(ostream& _stream, string const&) const @@ -276,6 +311,6 @@ void SemanticTest::parseExpectations(istream& _stream) bool SemanticTest::deploy(string const& _contractName, u256 const& _value, bytes const& _arguments, map const& _libraries) { - auto output = compileAndRunWithoutCheck(m_source, _value, _contractName, _arguments, _libraries); + auto output = compileAndRunWithoutCheck(m_sources.sources, _value, _contractName, _arguments, _libraries); return !output.empty() && m_transactionSuccessful; } diff --git a/test/libsolidity/SemanticTest.h b/test/libsolidity/SemanticTest.h index 870d61d56..646e7e00b 100644 --- a/test/libsolidity/SemanticTest.h +++ b/test/libsolidity/SemanticTest.h @@ -58,9 +58,8 @@ public: /// Compiles and deploys currently held source. /// Returns true if deployment was successful, false otherwise. bool deploy(std::string const& _contractName, u256 const& _value, bytes const& _arguments, std::map const& _libraries = {}); - private: - std::string m_source; + SourceMap m_sources; std::size_t m_lineOffset; std::vector m_tests; bool m_runWithYul = false; diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 83e7ef95d..d449cd27e 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -1746,7 +1746,7 @@ BOOST_AUTO_TEST_CASE(internal_constructor) constructor() internal {} } )"; - BOOST_CHECK(compileAndRunWithoutCheck(sourceCode, 0, "C").empty()); + BOOST_CHECK(compileAndRunWithoutCheck({{"", sourceCode}}, 0, "C").empty()); } BOOST_AUTO_TEST_CASE(default_fallback_throws) @@ -3641,7 +3641,7 @@ BOOST_AUTO_TEST_CASE(evm_exceptions_in_constructor_out_of_baund) } } )"; - ABI_CHECK(compileAndRunWithoutCheck(sourceCode, 0, "A"), encodeArgs()); + ABI_CHECK(compileAndRunWithoutCheck({{"", sourceCode}}, 0, "A"), encodeArgs()); BOOST_CHECK(!m_transactionSuccessful); } diff --git a/test/libsolidity/SolidityExecutionFramework.cpp b/test/libsolidity/SolidityExecutionFramework.cpp index 5e4ebe088..29b3b8b43 100644 --- a/test/libsolidity/SolidityExecutionFramework.cpp +++ b/test/libsolidity/SolidityExecutionFramework.cpp @@ -31,22 +31,18 @@ using namespace solidity::frontend; using namespace solidity::frontend::test; using namespace std; -bytes SolidityExecutionFramework::compileContract( - string const& _sourceCode, +bytes SolidityExecutionFramework::multiSourceCompileContract( + map const& _sourceCode, string const& _contractName, map const& _libraryAddresses ) { - // Silence compiler version warning - std::string sourceCode = "pragma solidity >=0.0;\n"; - if ( - solidity::test::CommonOptions::get().useABIEncoderV2 && - _sourceCode.find("pragma experimental ABIEncoderV2;") == std::string::npos - ) - sourceCode += "pragma experimental ABIEncoderV2;\n"; - sourceCode += _sourceCode; + map sourcesWithPreamble = _sourceCode; + for (auto& entry: sourcesWithPreamble) + entry.second = addPreamble(entry.second); + m_compiler.reset(); - m_compiler.setSources({{"", sourceCode}}); + m_compiler.setSources(sourcesWithPreamble); m_compiler.setLibraries(_libraryAddresses); m_compiler.setRevertStringBehaviour(m_revertStrings); m_compiler.setEVMVersion(m_evmVersion); @@ -85,3 +81,28 @@ bytes SolidityExecutionFramework::compileContract( cout << "metadata: " << m_compiler.metadata(contractName) << endl; return obj.bytecode; } + +bytes SolidityExecutionFramework::compileContract( + string const& _sourceCode, + string const& _contractName, + map const& _libraryAddresses +) +{ + return multiSourceCompileContract( + {{"", _sourceCode}}, + _contractName, + _libraryAddresses + ); +} + +string SolidityExecutionFramework::addPreamble(string const& _sourceCode) +{ + // Silence compiler version warning + string preamble = "pragma solidity >=0.0;\n"; + if ( + solidity::test::CommonOptions::get().useABIEncoderV2 && + _sourceCode.find("pragma experimental ABIEncoderV2;") == string::npos + ) + preamble += "pragma experimental ABIEncoderV2;\n"; + return preamble + _sourceCode; +} diff --git a/test/libsolidity/SolidityExecutionFramework.h b/test/libsolidity/SolidityExecutionFramework.h index 2410195fa..5be310c87 100644 --- a/test/libsolidity/SolidityExecutionFramework.h +++ b/test/libsolidity/SolidityExecutionFramework.h @@ -47,14 +47,14 @@ public: {} bytes const& compileAndRunWithoutCheck( - std::string const& _sourceCode, + std::map const& _sourceCode, u256 const& _value = 0, std::string const& _contractName = "", - bytes const& _arguments = bytes(), - std::map const& _libraryAddresses = std::map() + bytes const& _arguments = {}, + std::map const& _libraryAddresses = {} ) override { - bytes bytecode = compileContract(_sourceCode, _contractName, _libraryAddresses); + bytes bytecode = multiSourceCompileContract(_sourceCode, _contractName, _libraryAddresses); sendMessage(bytecode + _arguments, true, _value); return m_output; } @@ -62,16 +62,23 @@ public: bytes compileContract( std::string const& _sourceCode, std::string const& _contractName = "", - std::map const& _libraryAddresses = std::map() + std::map const& _libraryAddresses = {} ); + bytes multiSourceCompileContract( + std::map const& _sources, + std::string const& _contractName = "", + std::map const& _libraryAddresses = {} + ); + + /// Returns @param _sourceCode prefixed with the version pragma and the ABIEncoderV2 pragma, + /// the latter only if it is required. + static std::string addPreamble(std::string const& _sourceCode); protected: solidity::frontend::CompilerStack m_compiler; bool m_compileViaYul = false; bool m_showMetadata = false; RevertStrings m_revertStrings = RevertStrings::Default; - }; } // end namespaces - diff --git a/test/libsolidity/semanticTests/multiSource/import.sol b/test/libsolidity/semanticTests/multiSource/import.sol new file mode 100644 index 000000000..2a0f43d53 --- /dev/null +++ b/test/libsolidity/semanticTests/multiSource/import.sol @@ -0,0 +1,12 @@ +==== Source: A ==== +contract A { + function g(uint256 x) public view returns(uint256) { return x + 1; } +} +==== Source: B ==== +import "A"; +contract B is A { + function f(uint256 x) public view returns(uint256) { return x; } +} +// ---- +// f(uint256): 1337 -> 1337 +// g(uint256): 1337 -> 1338 diff --git a/test/tools/isoltest.cpp b/test/tools/isoltest.cpp index 846a54415..07802edf1 100644 --- a/test/tools/isoltest.cpp +++ b/test/tools/isoltest.cpp @@ -21,17 +21,13 @@ #include #include #include -#include #include #include -#include #include #include -#include #include -#include #include #include #include