Skip to content

Commit 70fa50f

Browse files
committed
FunctionCallGraph: Tests for constants, immutables and accessing function selectors
1 parent 2a52e46 commit 70fa50f

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed

test/libsolidity/analysis/FunctionCallGraph.cpp

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,6 +2000,153 @@ BOOST_AUTO_TEST_CASE(conversions_and_struct_array_constructors)
20002000
checkCallGraphExpectations(get<1>(graphs), expectedDeployedEdges);
20012001
}
20022002

2003+
BOOST_AUTO_TEST_CASE(immutable_initialization)
2004+
{
2005+
unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R"(
2006+
function free() pure returns (uint) { return 42; }
2007+
2008+
contract Base {
2009+
function ext() external pure returns (uint) { free(); }
2010+
function inr() internal pure returns (uint) { free(); }
2011+
}
2012+
2013+
contract C is Base {
2014+
uint immutable extImmutable = this.ext();
2015+
uint immutable inrImmutable = inr();
2016+
}
2017+
2018+
contract D is Base {
2019+
uint immutable extImmutable;
2020+
uint immutable inrImmutable;
2021+
2022+
constructor () {
2023+
extImmutable = this.ext();
2024+
inrImmutable = inr();
2025+
}
2026+
}
2027+
)"s);
2028+
tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);
2029+
2030+
map<string, EdgeNames> expectedCreationEdges = {
2031+
{"Base", {}},
2032+
{"C", {
2033+
{"Entry", "function Base.inr()"},
2034+
{"function Base.inr()", "function free()"},
2035+
}},
2036+
{"D", {
2037+
{"Entry", "constructor of D"},
2038+
{"constructor of D", "function Base.inr()"},
2039+
{"function Base.inr()", "function free()"},
2040+
}},
2041+
};
2042+
2043+
map<string, EdgeNames> expectedDeployedEdges = {
2044+
{"Base", {
2045+
{"Entry", "function Base.ext()"},
2046+
{"function Base.ext()", "function free()"},
2047+
}},
2048+
{"C", {
2049+
{"Entry", "function Base.ext()"},
2050+
{"function Base.ext()", "function free()"},
2051+
}},
2052+
{"D", {
2053+
{"Entry", "function Base.ext()"},
2054+
{"function Base.ext()", "function free()"},
2055+
}},
2056+
};
2057+
2058+
checkCallGraphExpectations(get<0>(graphs), expectedCreationEdges);
2059+
checkCallGraphExpectations(get<1>(graphs), expectedDeployedEdges);
2060+
}
2061+
2062+
BOOST_AUTO_TEST_CASE(function_selector_access)
2063+
{
2064+
unique_ptr<CompilerStack> compilerStack = parseAndAnalyzeContracts(R"(
2065+
function free() pure {}
2066+
2067+
bytes4 constant extFreeConst = Base.ext.selector;
2068+
bytes4 constant pubFreeConst = Base.pub.selector;
2069+
2070+
contract Base {
2071+
function ext() external pure { free(); }
2072+
function pub() public pure { free(); }
2073+
}
2074+
2075+
contract C is Base {
2076+
bytes4 constant extConst = Base.ext.selector;
2077+
bytes4 constant pubConst = Base.pub.selector;
2078+
}
2079+
2080+
contract D is Base {
2081+
bytes4 immutable extImmutable = Base.ext.selector;
2082+
bytes4 immutable pubImmutable = Base.pub.selector;
2083+
}
2084+
2085+
contract E is Base {
2086+
bytes4 extVar = Base.ext.selector;
2087+
bytes4 pubVar = Base.pub.selector;
2088+
}
2089+
2090+
contract F is Base {
2091+
function f() public pure returns (bytes4, bytes4) {
2092+
return (Base.ext.selector, Base.pub.selector);
2093+
}
2094+
}
2095+
2096+
library L {
2097+
bytes4 constant extConst = Base.ext.selector;
2098+
bytes4 constant pubConst = Base.pub.selector;
2099+
}
2100+
)"s);
2101+
tuple<CallGraphMap, CallGraphMap> graphs = collectGraphs(*compilerStack);
2102+
2103+
map<string, EdgeNames> expectedCreationEdges = {
2104+
{"Base", {}},
2105+
{"C", {}},
2106+
{"D", {}},
2107+
{"E", {}},
2108+
{"F", {}},
2109+
{"L", {}},
2110+
};
2111+
2112+
map<string, EdgeNames> expectedDeployedEdges = {
2113+
{"Base", {
2114+
{"Entry", "function Base.ext()"},
2115+
{"Entry", "function Base.pub()"},
2116+
{"function Base.ext()", "function free()"},
2117+
{"function Base.pub()", "function free()"},
2118+
}},
2119+
{"C", {
2120+
{"Entry", "function Base.ext()"},
2121+
{"Entry", "function Base.pub()"},
2122+
{"function Base.ext()", "function free()"},
2123+
{"function Base.pub()", "function free()"},
2124+
}},
2125+
{"D", {
2126+
{"Entry", "function Base.ext()"},
2127+
{"Entry", "function Base.pub()"},
2128+
{"function Base.ext()", "function free()"},
2129+
{"function Base.pub()", "function free()"},
2130+
}},
2131+
{"E", {
2132+
{"Entry", "function Base.ext()"},
2133+
{"Entry", "function Base.pub()"},
2134+
{"function Base.ext()", "function free()"},
2135+
{"function Base.pub()", "function free()"},
2136+
}},
2137+
{"F", {
2138+
{"Entry", "function Base.ext()"},
2139+
{"Entry", "function Base.pub()"},
2140+
{"function Base.ext()", "function free()"},
2141+
{"function Base.pub()", "function free()"},
2142+
}},
2143+
{"L", {}},
2144+
};
2145+
2146+
checkCallGraphExpectations(get<0>(graphs), expectedCreationEdges);
2147+
checkCallGraphExpectations(get<1>(graphs), expectedDeployedEdges);
2148+
}
2149+
20032150
BOOST_AUTO_TEST_SUITE_END()
20042151

20052152
} // namespace solidity::frontend::test

0 commit comments

Comments
 (0)