aboutsummaryrefslogtreecommitdiffstats
path: root/test/libsolidity
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-04-27 07:02:10 +0800
committerchriseth <c@ethdev.com>2016-05-04 04:41:18 +0800
commit7ea3d950d7001c12567c99aebdfc0fb73e46721e (patch)
tree6213ce320dd19905f041f585d624d1914f8ff157 /test/libsolidity
parentaa4dcbb88cd0096a79fa975ec353dfbc4e341f53 (diff)
downloaddexon-solidity-7ea3d950d7001c12567c99aebdfc0fb73e46721e.tar.gz
dexon-solidity-7ea3d950d7001c12567c99aebdfc0fb73e46721e.tar.zst
dexon-solidity-7ea3d950d7001c12567c99aebdfc0fb73e46721e.zip
Allow calling internal functions of libraries.
Internal functions of libraries can be called as if the library were a base contract of the calling contract. As the calling convention for internal functions is to not create a new call context, the code of these functions will be pulled into the context of the caller, duplicating their code. This might pull in code of further internal or even private functions. The use case for such functions is to allow libraries which can operate on memory types such that these types can also be modified in place.
Diffstat (limited to 'test/libsolidity')
-rw-r--r--test/libsolidity/SolidityEndToEndTest.cpp77
1 files changed, 77 insertions, 0 deletions
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index f9d2ab2b..6233e25f 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -6633,6 +6633,83 @@ BOOST_AUTO_TEST_CASE(delete_on_array_of_structs)
BOOST_CHECK(callContractFunction("f()") == encodeArgs(true));
}
+BOOST_AUTO_TEST_CASE(internal_library_function)
+{
+ // tests that internal library functions can be called from outside
+ // and retain the same memory context (i.e. are pulled into the caller's code)
+ char const* sourceCode = R"(
+ library L {
+ function f(uint[] _data) internal {
+ _data[3] = 2;
+ }
+ }
+ contract C {
+ function f() returns (uint) {
+ uint[] memory x = new uint[](7);
+ x[3] = 8;
+ L.f(x);
+ return x[3];
+ }
+ }
+ )";
+ // This has to work without linking, because everything will be inlined.
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2)));
+}
+
+BOOST_AUTO_TEST_CASE(internal_library_function_calling_private)
+{
+ // tests that internal library functions that are called from outside and that
+ // themselves call private functions are still able to (i.e. the private function
+ // also has to be pulled into the caller's code)
+ char const* sourceCode = R"(
+ library L {
+ function g(uint[] _data) private {
+ _data[3] = 2;
+ }
+ function f(uint[] _data) internal {
+ g(_data);
+ }
+ }
+ contract C {
+ function f() returns (uint) {
+ uint[] memory x = new uint[](7);
+ x[3] = 8;
+ L.f(x);
+ return x[3];
+ }
+ }
+ )";
+ // This has to work without linking, because everything will be inlined.
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2)));
+}
+
+BOOST_AUTO_TEST_CASE(internal_library_function_bound)
+{
+ char const* sourceCode = R"(
+ library L {
+ struct S { uint[] data; }
+ function f(S _s) internal {
+ _s.data[3] = 2;
+ }
+ }
+ contract C {
+ using L for L.S;
+ function f() returns (uint) {
+ L.S memory x;
+ x.data = new uint[](7);
+ x.data[3] = 8;
+ x.f();
+ return x.data[3];
+ }
+ }
+ )";
+ // This has to work without linking, because everything will be inlined.
+ compileAndRun(sourceCode, 0, "C");
+ BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(2)));
+}
+
BOOST_AUTO_TEST_SUITE_END()
}