Remove linking to unqualified library name

- SemanticTests accepts fully qualified library name and also unqualifed library name when
the library is defined in the same file for convenience.
- commandline tests are added!

Signed-off-by: soroosh-sdi <soroosh.sardari@gmail.com>
This commit is contained in:
soroosh-sdi 2021-10-01 09:18:52 +03:30
parent 1e630fc584
commit 816d8021e4
33 changed files with 242 additions and 64 deletions

View File

@ -20,7 +20,7 @@ Bugfixes:
* SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``).
* TypeChecker: Fix internal error when using user defined value types in public library functions.
* Yul IR Generator: Do not output empty switches/if-bodies for empty contracts.
* Commandline Interface: When linking only accept exact matches for library names passed to the ``--libraries`` option. Library names not prefixed with a file name used to match any library with that name.

View File

@ -73,14 +73,6 @@ LinkerObject::matchLibrary(
)
{
auto it = _libraryAddresses.find(_linkRefName);
if (it != _libraryAddresses.end())
return &it->second;
// If the user did not supply a fully qualified library name,
// try to match only the simple library name
size_t colon = _linkRefName.find(':');
if (colon == string::npos)
return nullptr;
it = _libraryAddresses.find(_linkRefName.substr(colon + 1));
if (it != _libraryAddresses.end())
return &it->second;
return nullptr;

View File

@ -0,0 +1 @@
linking_qualified_library_name/contract1.sol --bin --libraries linking_qualified_library_name/math.sol:Log:0x7777777777777777777777777777777777777777

View File

@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
import "linking_qualified_library_name/math.sol";
contract C {
function foo() public {
Log.log10();
}
}

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
library Log {
function log10() external {}
}

View File

@ -0,0 +1,8 @@
======= linking_qualified_library_name/contract1.sol:C =======
Binary:
<BYTECODE REMOVED>
======= linking_qualified_library_name/math.sol:Log =======
Binary:
<BYTECODE REMOVED>

View File

@ -1,26 +0,0 @@
======= linking_strict_assembly_no_file_name_in_link_reference/input.yul (EVM) =======
Pretty printed source:
object "a" {
code {
let addr := linkersymbol("L")
sstore(0, addr)
}
}
Binary representation:
7312345678901234567890123456789012345678908060005550
Text representation:
/* "linking_strict_assembly_no_file_name_in_link_reference/input.yul":44:61 */
linkerSymbol("8aa64f937099b65a4febc243a5ae0f2d6416bb9e473c30dd29c1ee498fb7c5a8")
/* "linking_strict_assembly_no_file_name_in_link_reference/input.yul":80:84 */
dup1
/* "linking_strict_assembly_no_file_name_in_link_reference/input.yul":77:78 */
0x00
/* "linking_strict_assembly_no_file_name_in_link_reference/input.yul":70:85 */
sstore
/* "linking_strict_assembly_no_file_name_in_link_reference/input.yul":22:91 */
pop

View File

@ -0,0 +1 @@
--strict-assembly --libraries :L=0x1234567890123456789012345678901234567890 --debug-info none

View File

@ -0,0 +1,6 @@
object "a" {
code {
let addr := linkersymbol(":L")
sstore(0, addr)
}
}

View File

@ -0,0 +1,21 @@
======= linking_strict_assembly_qualified_library_qualified_reference/input.yul (EVM) =======
Pretty printed source:
object "a" {
code {
let addr := linkersymbol(":L")
sstore(0, addr)
}
}
Binary representation:
7312345678901234567890123456789012345678908060005550
Text representation:
linkerSymbol("20a18a9bf97d889dcf77111b674da319a4e9e3e05d3f4df9e0bf5c588dd4f0f8")
dup1
0x00
sstore
pop

View File

@ -0,0 +1 @@
--strict-assembly --libraries :L=0x1234567890123456789012345678901234567890 --debug-info none

View File

@ -0,0 +1 @@
Warning: Yul is still experimental. Please use the output with care.

View File

@ -0,0 +1,21 @@
======= linking_strict_assembly_qualified_library_unqualified_reference/input.yul (EVM) =======
Pretty printed source:
object "a" {
code {
let addr := linkersymbol("L")
sstore(0, addr)
}
}
Binary representation:
73__$8aa64f937099b65a4febc243a5ae0f2d64$__8060005550
Text representation:
linkerSymbol("8aa64f937099b65a4febc243a5ae0f2d6416bb9e473c30dd29c1ee498fb7c5a8")
dup1
0x00
sstore
pop

View File

@ -1 +1 @@
--strict-assembly --libraries L=0x1234567890123456789012345678901234567890
--strict-assembly --libraries L=0x1234567890123456789012345678901234567890 --debug-info none

View File

@ -0,0 +1 @@
Warning: Yul is still experimental. Please use the output with care.

View File

@ -0,0 +1,6 @@
object "a" {
code {
let addr := linkersymbol(":L")
sstore(0, addr)
}
}

View File

@ -0,0 +1,21 @@
======= linking_strict_assembly_unqualified_library_qualified_reference/input.yul (EVM) =======
Pretty printed source:
object "a" {
code {
let addr := linkersymbol(":L")
sstore(0, addr)
}
}
Binary representation:
73__$20a18a9bf97d889dcf77111b674da319a4$__8060005550
Text representation:
linkerSymbol("20a18a9bf97d889dcf77111b674da319a4e9e3e05d3f4df9e0bf5c588dd4f0f8")
dup1
0x00
sstore
pop

View File

@ -0,0 +1 @@
--strict-assembly --libraries L=0x1234567890123456789012345678901234567890 --debug-info none

View File

@ -0,0 +1 @@
Warning: Yul is still experimental. Please use the output with care.

View File

@ -0,0 +1,6 @@
object "a" {
code {
let addr := linkersymbol("L")
sstore(0, addr)
}
}

View File

@ -0,0 +1,21 @@
======= linking_strict_assembly_unqualified_library_unqualified_reference/input.yul (EVM) =======
Pretty printed source:
object "a" {
code {
let addr := linkersymbol("L")
sstore(0, addr)
}
}
Binary representation:
7312345678901234567890123456789012345678908060005550
Text representation:
linkerSymbol("8aa64f937099b65a4febc243a5ae0f2d6416bb9e473c30dd29c1ee498fb7c5a8")
dup1
0x00
sstore
pop

View File

@ -0,0 +1 @@
linking_unqualified_library_name/contract1.sol linking_unqualified_library_name/contract2.sol --bin --libraries Log:0x7777777777777777777777777777777777777777

View File

@ -0,0 +1,11 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
import "linking_unqualified_library_name/error.sol";
contract C {
function foo() public {
Log.print();
}
}

View File

@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
import "linking_unqualified_library_name/math.sol";
contract C {
function foo() public {
Log.log10();
}
}

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
library Log {
function print() external {}
}

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.0;
library Log {
function log10() external {}
}

View File

@ -0,0 +1,20 @@
======= linking_unqualified_library_name/contract1.sol:C =======
Binary:
<BYTECODE REMOVED>__$cdf6d5ab08a9335b02e7c2475aa27d04fa$__<BYTECODE REMOVED>
// $cdf6d5ab08a9335b02e7c2475aa27d04fa$ -> linking_unqualified_library_name/error.sol:Log
======= linking_unqualified_library_name/contract2.sol:C =======
Binary:
<BYTECODE REMOVED>__$22584241c2fc4f2884d5222245463779a8$__<BYTECODE REMOVED>
// $22584241c2fc4f2884d5222245463779a8$ -> linking_unqualified_library_name/math.sol:Log
======= linking_unqualified_library_name/error.sol:Log =======
Binary:
<BYTECODE REMOVED>
======= linking_unqualified_library_name/math.sol:Log =======
Binary:
<BYTECODE REMOVED>

View File

@ -31,6 +31,7 @@
#include <memory>
#include <optional>
#include <stdexcept>
#include <string>
#include <utility>
using namespace std;
@ -383,7 +384,13 @@ TestCase::TestResult SemanticTest::runTest(
soltestAssert(
deploy(test.call().signature, 0, {}, libraries) && m_transactionSuccessful,
"Failed to deploy library " + test.call().signature);
libraries[test.call().signature] = m_contractAddress;
// For convenience, in semantic tests we assume that an unqualified name like `L` is equivalent to one
// with an empty source unit name (`:L`). This is fine because the compiler never uses unqualified
// names in the Yul code it produces and does not allow `linkersymbol()` at all in inline assembly.
if (test.call().signature.find(':') == string::npos)
libraries[":" + test.call().signature] = m_contractAddress;
else
libraries[test.call().signature] = m_contractAddress;
continue;
}
else

View File

@ -1565,7 +1565,7 @@ BOOST_AUTO_TEST_CASE(library_call_in_homestead)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs());
ABI_CHECK(callContractFunction("sender()"), encodeArgs(m_sender));
)
@ -1598,7 +1598,7 @@ BOOST_AUTO_TEST_CASE(library_call_protection)
ABI_CHECK(callContractFunction("np(Lib.S storage)", 0), encodeArgs());
ABI_CHECK(callContractFunction("v(Lib.S storage)", 0), encodeArgs(m_sender));
ABI_CHECK(callContractFunction("pu()"), encodeArgs(2));
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("s()"), encodeArgs(0));
ABI_CHECK(callContractFunction("np()"), encodeArgs(m_sender));
ABI_CHECK(callContractFunction("s()"), encodeArgs(3));
@ -1627,7 +1627,7 @@ BOOST_AUTO_TEST_CASE(library_staticcall_delegatecall)
}
)";
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(1));
}
@ -1883,7 +1883,7 @@ BOOST_AUTO_TEST_CASE(struct_referencing)
compileAndRun(sourceCode, 0, "L");
ABI_CHECK(callContractFunction("f()"), encodeArgs(0, 3));
ABI_CHECK(callContractFunction("g()"), encodeArgs(4));
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{ {"L", m_contractAddress}});
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{ {":L", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(1));
ABI_CHECK(callContractFunction("g()"), encodeArgs(2));
ABI_CHECK(callContractFunction("h()"), encodeArgs(0, 5));
@ -1932,7 +1932,7 @@ BOOST_AUTO_TEST_CASE(enum_referencing)
compileAndRun(sourceCode, 0, "L");
ABI_CHECK(callContractFunction("f()"), encodeArgs(1));
ABI_CHECK(callContractFunction("g()"), encodeArgs(3));
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"L", m_contractAddress}});
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{":L", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(3));
ABI_CHECK(callContractFunction("g()"), encodeArgs(3));
ABI_CHECK(callContractFunction("h()"), encodeArgs(1));
@ -2763,7 +2763,7 @@ BOOST_AUTO_TEST_CASE(library_call)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(33)), encodeArgs(u256(33) * 9));
)
}
@ -2781,7 +2781,7 @@ BOOST_AUTO_TEST_CASE(library_function_external)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f(bytes)", u256(0x20), u256(5), "abcde"), encodeArgs("c"));
)
}
@ -2801,7 +2801,7 @@ BOOST_AUTO_TEST_CASE(library_stray_values)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(33)), encodeArgs(u256(42)));
)
}
@ -2834,7 +2834,7 @@ BOOST_AUTO_TEST_CASE(internal_types_in_library)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(4), u256(17)));
)
}
@ -2868,7 +2868,7 @@ BOOST_AUTO_TEST_CASE(mapping_arguments_in_library)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(1), u256(42)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(2), u256(84)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("set(uint256,uint256)", u256(21), u256(7)), encodeArgs(u256(0)));
@ -2919,7 +2919,7 @@ BOOST_AUTO_TEST_CASE(mapping_returns_in_library)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(1), u256(42)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(2), u256(84)), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("set(bool,uint256,uint256)", true, u256(21), u256(7)), encodeArgs(u256(0)));
@ -2998,7 +2998,7 @@ BOOST_AUTO_TEST_CASE(mapping_returns_in_library_named)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(0), u256(42), u256(0), u256(0), u256(21), u256(84)));
ABI_CHECK(callContractFunction("g()"), encodeArgs(u256(0), u256(42), u256(0), u256(0), u256(21), u256(17)));
)
@ -3029,7 +3029,7 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_public)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1), u256(0), u256(42), u256(23), u256(0), u256(99)));
)
}
@ -3065,7 +3065,7 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_external)
{
string prefix = "pragma abicoder " + string(v2 ? "v2" : "v1") + ";\n";
compileAndRun(prefix + libSourceCode, 0, "Lib");
compileAndRun(prefix + sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(prefix + sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(2), u256(0), u256(84), u256(46), u256(0), u256(198)));
}
}
@ -3093,7 +3093,7 @@ BOOST_AUTO_TEST_CASE(using_library_mappings_return)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(1), u256(0), u256(42), u256(23), u256(0), u256(99)));
)
}
@ -3124,7 +3124,7 @@ BOOST_AUTO_TEST_CASE(using_library_structs)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "Lib");
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"Lib", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":Lib", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7), u256(8)));
)
}
@ -3340,7 +3340,7 @@ BOOST_AUTO_TEST_CASE(using_for_function_on_struct)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}});
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{":D", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(3 * 7)));
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(3 * 7)));
)
@ -3366,7 +3366,7 @@ BOOST_AUTO_TEST_CASE(using_for_overload)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}});
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{":D", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7)));
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7)));
)
@ -3388,7 +3388,7 @@ BOOST_AUTO_TEST_CASE(using_for_by_name)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}});
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{":D", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7)));
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7)));
)
@ -3411,7 +3411,7 @@ BOOST_AUTO_TEST_CASE(bound_function_in_function)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "L");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"L", m_contractAddress}});
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{":L", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(7)));
)
}
@ -3432,7 +3432,7 @@ BOOST_AUTO_TEST_CASE(bound_function_in_var)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}});
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{":D", m_contractAddress}});
ABI_CHECK(callContractFunction("f(uint256)", u256(7)), encodeArgs(u256(6 * 7)));
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(6 * 7)));
)
@ -3458,7 +3458,7 @@ BOOST_AUTO_TEST_CASE(bound_function_to_string)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "D");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"D", m_contractAddress}});
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{":D", m_contractAddress}});
ABI_CHECK(callContractFunction("f()"), encodeArgs(u256(3)));
ABI_CHECK(callContractFunction("g()"), encodeArgs(u256(3)));
)
@ -3631,7 +3631,7 @@ BOOST_AUTO_TEST_CASE(payable_function_calls_library)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "L");
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{"L", m_contractAddress}});
compileAndRun(sourceCode, 0, "C", bytes(), map<string, h160>{{":L", m_contractAddress}});
ABI_CHECK(callContractFunctionWithValue("f()", 27), encodeArgs(u256(7)));
)
}
@ -4720,7 +4720,7 @@ BOOST_AUTO_TEST_CASE(event_wrong_abi_name)
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode, 0, "ClientReceipt", bytes());
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{"ClientReceipt", m_contractAddress}});
compileAndRun(sourceCode, 0, "Test", bytes(), map<string, h160>{{":ClientReceipt", m_contractAddress}});
callContractFunction("f()");
BOOST_REQUIRE_EQUAL(numLogs(), 1);

View File

@ -42,7 +42,7 @@ contract C {
// EVMVersion: >=byzantium
// compileViaYul: also
// ----
// library: L
// library: "a.sol":L
// addr() -> false
// g(uint256): 1 -> 1
// g(uint256): 2 -> 4

View File

@ -100,8 +100,26 @@ vector<solidity::frontend::test::FunctionCall> TestFileParser::parseFunctionCall
if (accept(Token::Library, true))
{
expect(Token::Colon);
call.signature = m_scanner.currentLiteral();
expect(Token::Identifier);
string libraryName;
if (accept(Token::String))
{
libraryName = m_scanner.currentLiteral();
expect(Token::String);
expect(Token::Colon);
libraryName += ':' + m_scanner.currentLiteral();
expect(Token::Identifier);
}
else if (accept(Token::Colon, true))
{
libraryName = ':' + m_scanner.currentLiteral();
expect(Token::Identifier);
}
else
{
libraryName = m_scanner.currentLiteral();
expect(Token::Identifier);
}
call.signature = libraryName;
call.kind = FunctionCall::Kind::Library;
call.expectations.failure = false;
}