Skip to content

Commit 8ae7765

Browse files
committed
Do not use named function labels if function names are not unique.
1 parent 3713d6d commit 8ae7765

File tree

6 files changed

+137
-2
lines changed

6 files changed

+137
-2
lines changed

Changelog.md

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ Bugfixes:
1919
* Commandline Interface: Don't return zero exit code when writing linked files to disk fails.
2020
* SMTChecker: Fix internal error in magic type access (``block``, ``msg``, ``tx``).
2121
* TypeChecker: Fix internal error when using user defined value types in public library functions.
22+
* Yul Assembler: Fix internal error when function names are not unique.
2223
* Yul IR Generator: Do not output empty switches/if-bodies for empty contracts.
2324

2425

libyul/backends/evm/EVMObjectCompiler.cpp

+29-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,30 @@
3030
using namespace solidity::yul;
3131
using namespace std;
3232

33+
namespace
34+
{
35+
class AreFunctionNamesUnique: ASTWalker
36+
{
37+
public:
38+
static bool check(Block& _block)
39+
{
40+
AreFunctionNamesUnique instance;
41+
instance(_block);
42+
return instance.m_unique;
43+
}
44+
private:
45+
using ASTWalker::operator();
46+
void operator()(FunctionDefinition const& _functionDefinition) override
47+
{
48+
ASTWalker::operator()(_functionDefinition);
49+
if (!m_functionNames.insert(_functionDefinition.name).second)
50+
m_unique = false;
51+
}
52+
bool m_unique = true;
53+
std::set<YulString> m_functionNames;
54+
};
55+
}
56+
3357
void EVMObjectCompiler::compile(Object& _object, AbstractAssembly& _assembly, EVMDialect const& _dialect, bool _optimize)
3458
{
3559
EVMObjectCompiler compiler(_assembly, _dialect);
@@ -62,6 +86,10 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize)
6286

6387
yulAssert(_object.analysisInfo, "No analysis info.");
6488
yulAssert(_object.code, "No code.");
89+
90+
// We cannot use named labels if the function names are not unique.
91+
bool useNamedLabelsForFunctions = AreFunctionNamesUnique::check(*_object.code);
92+
6593
// We do not catch and re-throw the stack too deep exception here because it is a YulException,
6694
// which should be native to this part of the code.
6795
CodeTransform transform{
@@ -72,7 +100,7 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize)
72100
context,
73101
_optimize,
74102
{},
75-
true /* _useNamedLabelsForFunctions */
103+
useNamedLabelsForFunctions
76104
};
77105
transform(*_object.code);
78106
if (!transform.stackErrors().empty())

libyul/optimiser/Disambiguator.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class Disambiguator: public ASTCopier
5555
void enterScope(Block const& _block) override;
5656
void leaveScope(Block const& _block) override;
5757
void enterFunction(FunctionDefinition const& _function) override;
58-
void leaveFunction(FunctionDefinition const& _function) override;
58+
void leaveFunction (FunctionDefinition const& _function) override;
5959
YulString translateIdentifier(YulString _name) override;
6060

6161
void enterScopeInternal(Scope& _scope);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--strict-assembly
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
object "object" {
2+
code {
3+
let a
4+
let b
5+
{
6+
function z() -> y
7+
{ y := calldataload(0) }
8+
a := z()
9+
}
10+
{
11+
function z() -> y
12+
{ y := calldataload(0x20) }
13+
b := z()
14+
}
15+
sstore(a, b)
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
2+
======= yul_function_name_clashes/input.yul (EVM) =======
3+
4+
Pretty printed source:
5+
object "object" {
6+
code {
7+
let a
8+
let b
9+
{
10+
function z() -> y
11+
{ y := calldataload(0) }
12+
a := z()
13+
}
14+
{
15+
function z() -> y
16+
{ y := calldataload(0x20) }
17+
b := z()
18+
}
19+
sstore(a, b)
20+
}
21+
}
22+
23+
24+
Binary representation:
25+
600080600f565b60008035905090565b60156006565b91506025565b6000602035905090565b602b601b565b90508082555050
26+
27+
Text representation:
28+
/* "yul_function_name_clashes/input.yul":37:42 */
29+
0x00
30+
/* "yul_function_name_clashes/input.yul":51:56 */
31+
dup1
32+
/* "yul_function_name_clashes/input.yul":79:133 */
33+
jump(tag_2)
34+
tag_1:
35+
/* "yul_function_name_clashes/input.yul":95:96 */
36+
0x00
37+
/* "yul_function_name_clashes/input.yul":129:130 */
38+
dup1
39+
/* "yul_function_name_clashes/input.yul":116:131 */
40+
calldataload
41+
/* "yul_function_name_clashes/input.yul":111:131 */
42+
swap1
43+
pop
44+
/* "yul_function_name_clashes/input.yul":79:133 */
45+
swap1
46+
jump // out
47+
tag_2:
48+
/* "yul_function_name_clashes/input.yul":151:154 */
49+
tag_4
50+
tag_1
51+
jump // in
52+
tag_4:
53+
/* "yul_function_name_clashes/input.yul":146:154 */
54+
swap2
55+
pop
56+
/* "yul_function_name_clashes/input.yul":187:244 */
57+
jump(tag_6)
58+
tag_5:
59+
/* "yul_function_name_clashes/input.yul":203:204 */
60+
0x00
61+
/* "yul_function_name_clashes/input.yul":237:241 */
62+
0x20
63+
/* "yul_function_name_clashes/input.yul":224:242 */
64+
calldataload
65+
/* "yul_function_name_clashes/input.yul":219:242 */
66+
swap1
67+
pop
68+
/* "yul_function_name_clashes/input.yul":187:244 */
69+
swap1
70+
jump // out
71+
tag_6:
72+
/* "yul_function_name_clashes/input.yul":262:265 */
73+
tag_8
74+
tag_5
75+
jump // in
76+
tag_8:
77+
/* "yul_function_name_clashes/input.yul":257:265 */
78+
swap1
79+
pop
80+
/* "yul_function_name_clashes/input.yul":294:295 */
81+
dup1
82+
/* "yul_function_name_clashes/input.yul":291:292 */
83+
dup3
84+
/* "yul_function_name_clashes/input.yul":284:296 */
85+
sstore
86+
/* "yul_function_name_clashes/input.yul":27:302 */
87+
pop
88+
pop

0 commit comments

Comments
 (0)