From 1f30982ab532fdf719f3924e24e80057fe85e031 Mon Sep 17 00:00:00 2001 From: Rhett Aultman Date: Wed, 21 Dec 2016 11:26:22 -0800 Subject: [PATCH] Use fully-qualified names for linking, too Using libraries leaves behind a library link reference in the binary which the linker must later resolve. These link references were still being generated by name and not by fully-qualified name. This would lead to a link-time collision between two libraries having the same name but in different source units. This change changes linker symbols over to fully-qualified names, which resolves that issue. This does potentially introduce a new problem, which is that linker symbols appear to be limited to 36 characters and are truncated. Storing paths extends the average symbol size, and it would be great if truncation was from the tail rather than the head. --- libsolidity/codegen/ContractCompiler.cpp | 2 +- libsolidity/codegen/ExpressionCompiler.cpp | 4 ++-- test/libsolidity/SolidityEndToEndTest.cpp | 24 +++++++++++----------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index a0f196bc3..fa77c1aad 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -575,7 +575,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly) else if (auto contract = dynamic_cast(decl)) { solAssert(contract->isLibrary(), ""); - _assembly.appendLibraryAddress(contract->name()); + _assembly.appendLibraryAddress(contract->fullyQualifiedName()); } else solAssert(false, "Invalid declaration type."); diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 3922da881..37bd14583 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -892,7 +892,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) solAssert(funType->location() == FunctionType::Location::DelegateCall, ""); auto contract = dynamic_cast(funType->declaration().scope()); solAssert(contract && contract->isLibrary(), ""); - m_context.appendLibraryAddress(contract->name()); + m_context.appendLibraryAddress(contract->fullyQualifiedName()); m_context << funType->externalIdentifier(); utils().moveIntoStack(funType->selfType()->sizeOnStack(), 2); } @@ -1270,7 +1270,7 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier) else if (auto contract = dynamic_cast(declaration)) { if (contract->isLibrary()) - m_context.appendLibraryAddress(contract->name()); + m_context.appendLibraryAddress(contract->fullyQualifiedName()); } else if (dynamic_cast(declaration)) { diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 191618317..03aa26999 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -3192,7 +3192,7 @@ BOOST_AUTO_TEST_CASE(library_call_in_homestead) } )"; compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); BOOST_CHECK(callContractFunction("f()") == encodeArgs()); BOOST_CHECK(callContractFunction("sender()") == encodeArgs(u160(m_sender))); } @@ -6191,7 +6191,7 @@ BOOST_AUTO_TEST_CASE(library_call) } )"; compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); BOOST_CHECK(callContractFunction("f(uint256)", u256(33)) == encodeArgs(u256(33) * 9)); } @@ -6208,7 +6208,7 @@ BOOST_AUTO_TEST_CASE(library_stray_values) } )"; compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); BOOST_CHECK(callContractFunction("f(uint256)", u256(33)) == encodeArgs(u256(42))); } @@ -6341,7 +6341,7 @@ BOOST_AUTO_TEST_CASE(internal_types_in_library) } )"; compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(4), u256(17))); } @@ -6368,7 +6368,7 @@ BOOST_AUTO_TEST_CASE(using_library_structs) } )"; compileAndRun(sourceCode, 0, "Lib"); - compileAndRun(sourceCode, 0, "Test", bytes(), map{{"Lib", m_contractAddress}}); + compileAndRun(sourceCode, 0, "Test", bytes(), map{{":Lib", m_contractAddress}}); BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7), u256(8))); } @@ -6902,7 +6902,7 @@ BOOST_AUTO_TEST_CASE(using_for_function_on_int) } )"; compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); BOOST_CHECK(callContractFunction("f(uint256)", u256(9)) == encodeArgs(u256(2 * 9))); } @@ -6920,7 +6920,7 @@ BOOST_AUTO_TEST_CASE(using_for_function_on_struct) } )"; compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(3 * 7))); BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(3 * 7))); } @@ -6943,7 +6943,7 @@ BOOST_AUTO_TEST_CASE(using_for_overload) } )"; compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(6 * 7))); BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(6 * 7))); } @@ -6962,7 +6962,7 @@ BOOST_AUTO_TEST_CASE(using_for_by_name) } )"; compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(6 * 7))); BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(6 * 7))); } @@ -6982,7 +6982,7 @@ BOOST_AUTO_TEST_CASE(bound_function_in_var) } )"; compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); BOOST_CHECK(callContractFunction("f(uint256)", u256(7)) == encodeArgs(u256(6 * 7))); BOOST_CHECK(callContractFunction("x()") == encodeArgs(u256(6 * 7))); } @@ -7005,7 +7005,7 @@ BOOST_AUTO_TEST_CASE(bound_function_to_string) } )"; compileAndRun(sourceCode, 0, "D"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"D", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":D", m_contractAddress}}); BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(3))); BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(3))); } @@ -7751,7 +7751,7 @@ BOOST_AUTO_TEST_CASE(payable_function_calls_library) } )"; compileAndRun(sourceCode, 0, "L"); - compileAndRun(sourceCode, 0, "C", bytes(), map{{"L", m_contractAddress}}); + compileAndRun(sourceCode, 0, "C", bytes(), map{{":L", m_contractAddress}}); BOOST_CHECK(callContractFunctionWithValue("f()", 27) == encodeArgs(u256(7))); }