diff --git a/SolidityCompiler.cpp b/SolidityCompiler.cpp index 53daa9dfe..98397af79 100644 --- a/SolidityCompiler.cpp +++ b/SolidityCompiler.cpp @@ -108,57 +108,6 @@ BOOST_AUTO_TEST_CASE(smoke_test) checkCodePresentAt(code, expectation, boilerplateSize); } -BOOST_AUTO_TEST_CASE(different_argument_numbers) -{ - char const* sourceCode = "contract test {\n" - " function f(uint a, uint b, uint c) returns(uint d) { return b; }\n" - " function g() returns (uint e, uint h) { h = f(1, 2, 3); }\n" - "}\n"; - bytes code = compileContract(sourceCode); - unsigned shift = 103; - unsigned boilerplateSize = 116; - bytes expectation({byte(Instruction::JUMPDEST), - byte(Instruction::PUSH1), 0x0, // initialize return variable d - byte(Instruction::DUP3), - byte(Instruction::SWAP1), // assign b to d - byte(Instruction::POP), - byte(Instruction::PUSH1), byte(0xa + shift), // jump to return - byte(Instruction::JUMP), - byte(Instruction::JUMPDEST), - byte(Instruction::SWAP4), // store d and fetch return address - byte(Instruction::SWAP3), // store return address - byte(Instruction::POP), - byte(Instruction::POP), - byte(Instruction::POP), - byte(Instruction::JUMP), // end of f - byte(Instruction::JUMPDEST), // beginning of g - byte(Instruction::PUSH1), 0x0, - byte(Instruction::PUSH1), 0x0, // initialized e and h - byte(Instruction::PUSH1), byte(0x21 + shift), // ret address - byte(Instruction::PUSH1), 0x1, - byte(Instruction::PUSH1), 0x2, - byte(Instruction::PUSH1), 0x3, - byte(Instruction::PUSH1), byte(0x1 + shift), - // stack here: ret e h 0x20 1 2 3 0x1 - byte(Instruction::JUMP), - byte(Instruction::JUMPDEST), - // stack here: ret e h f(1,2,3) - byte(Instruction::SWAP1), - // stack here: ret e f(1,2,3) h - byte(Instruction::POP), - byte(Instruction::DUP1), // retrieve it again as "value of expression" - byte(Instruction::POP), // end of assignment - // stack here: ret e f(1,2,3) - byte(Instruction::JUMPDEST), - byte(Instruction::SWAP1), - // ret e f(1,2,3) - byte(Instruction::SWAP2), - // f(1,2,3) e ret - byte(Instruction::JUMP) // end of g - }); - checkCodePresentAt(code, expectation, boilerplateSize); -} - BOOST_AUTO_TEST_CASE(ifStatement) { char const* sourceCode = "contract test {\n" diff --git a/SolidityEndToEndTest.cpp b/SolidityEndToEndTest.cpp index 1ddb22731..1450095af 100644 --- a/SolidityEndToEndTest.cpp +++ b/SolidityEndToEndTest.cpp @@ -1930,6 +1930,30 @@ BOOST_AUTO_TEST_CASE(crazy_elementary_typenames_on_stack) BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(-7))); } +BOOST_AUTO_TEST_CASE(super) +{ + char const* sourceCode = R"( + contract A { function f() returns (uint r) { return 1; } } + contract B is A { function f() returns (uint r) { return super.f() | 2; } } + contract C is A { function f() returns (uint r) { return super.f() | 4; } } + contract D is B, C { function f() returns (uint r) { return super.f() | 8; } } + )"; + compileAndRun(sourceCode, 0, "D"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(1 | 2 | 4 | 8)); +} + +BOOST_AUTO_TEST_CASE(super_in_constructor) +{ + char const* sourceCode = R"( + contract A { function f() returns (uint r) { return 1; } } + contract B is A { function f() returns (uint r) { return super.f() | 2; } } + contract C is A { function f() returns (uint r) { return super.f() | 4; } } + contract D is B, C { uint data; function D() { data = super.f() | 8; } function f() returns (uint r) { return data; } } + )"; + compileAndRun(sourceCode, 0, "D"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(1 | 2 | 4 | 8)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/SolidityExpressionCompiler.cpp b/SolidityExpressionCompiler.cpp index 06c252db3..a0cca3a3a 100644 --- a/SolidityExpressionCompiler.cpp +++ b/SolidityExpressionCompiler.cpp @@ -86,7 +86,8 @@ Declaration const& resolveDeclaration(vector const& _namespacedName, } bytes compileFirstExpression(const string& _sourceCode, vector> _functions = {}, - vector> _localVariables = {}, vector> _globalDeclarations = {}) + vector> _localVariables = {}, + vector> _globalDeclarations = {}) { Parser parser; ASTPointer sourceUnit; @@ -99,10 +100,12 @@ bytes compileFirstExpression(const string& _sourceCode, vector> _ NameAndTypeResolver resolver(declarations); resolver.registerDeclarations(*sourceUnit); + vector inheritanceHierarchy; for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) { BOOST_REQUIRE_NO_THROW(resolver.resolveNamesAndTypes(*contract)); + inheritanceHierarchy = vector(1, contract); } for (ASTPointer const& node: sourceUnit->getNodes()) if (ContractDefinition* contract = dynamic_cast(node.get())) @@ -116,8 +119,7 @@ bytes compileFirstExpression(const string& _sourceCode, vector> _ BOOST_REQUIRE(extractor.getExpression() != nullptr); CompilerContext context; - for (vector const& function: _functions) - context.addFunction(dynamic_cast(resolveDeclaration(function, resolver))); + context.setInheritanceHierarchy(inheritanceHierarchy); unsigned parametersSize = _localVariables.size(); // assume they are all one slot on the stack context.adjustStackOffset(parametersSize); for (vector const& variable: _localVariables)