Skip to content

Commit d2399ad

Browse files
committed
Fix unnecessary tuple conversion
1 parent e0fd216 commit d2399ad

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

libsolidity/ast/Types.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2766,7 +2766,20 @@ std::string TupleType::richIdentifier() const
27662766
bool TupleType::operator==(Type const& _other) const
27672767
{
27682768
if (auto tupleType = dynamic_cast<TupleType const*>(&_other))
2769-
return components() == tupleType->components();
2769+
{
2770+
if (components().size() != tupleType->components().size())
2771+
return false;
2772+
2773+
for (size_t i = 0; i < components().size(); ++i)
2774+
{
2775+
if (components()[i] && tupleType->components()[i] && *components()[i] != *tupleType->components()[i])
2776+
return false;
2777+
else if (components()[i] != tupleType->components()[i])
2778+
return false;
2779+
}
2780+
2781+
return true;
2782+
}
27702783
else
27712784
return false;
27722785
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// SPDX-License-Identifier: GPL-3.0
2+
pragma solidity >= 0.0.0;
3+
4+
contract C {
5+
function g_int(uint[] calldata a) public pure returns(uint[] memory, uint[] calldata) {
6+
uint[] memory ops1; // we take two arrays so the compiler won't short-circuit the conditional
7+
uint[] memory ops2;
8+
9+
(uint[] memory a1, uint[] calldata b1) = true ? (ops1, a) : (ops2, a);
10+
11+
return (a1, b1);
12+
}
13+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import sys
5+
import subprocess
6+
from pathlib import Path
7+
from textwrap import dedent
8+
9+
# pylint: disable=wrong-import-position
10+
PROJECT_ROOT = Path(__file__).parents[3]
11+
sys.path.insert(0, str(PROJECT_ROOT / 'scripts'))
12+
13+
from common.cmdline_helpers import add_preamble
14+
from common.cmdline_helpers import inside_temporary_dir
15+
from common.cmdline_helpers import save_bytecode
16+
from common.cmdline_helpers import solc_bin_report
17+
from common.git_helpers import git_diff
18+
from splitSources import split_sources
19+
20+
21+
@inside_temporary_dir(Path(__file__).parent.name)
22+
def test_no_convert_fun_generated():
23+
source_file_path = Path(__file__).parent / 'input.sol'
24+
add_preamble(Path.cwd())
25+
26+
solc_binary = os.environ.get('SOLC')
27+
if solc_binary is None:
28+
raise RuntimeError(dedent("""\
29+
`solc` compiler not found.
30+
Please ensure you set the SOLC environment variable
31+
with the correct path to the compiler's binary.
32+
"""))
33+
34+
output = subprocess.check_output(
35+
[solc_binary]
36+
+ [source_file_path]
37+
+ (["--ir"])
38+
+ (["--optimize"]),
39+
encoding="utf8",
40+
)
41+
42+
# This test verifies that the compiler does not generate a function converting between tuples of the same types.
43+
assert "function convert_" not in output, "Output should not contain 'function convert_*'"
44+
45+
return 0
46+
47+
48+
if __name__ == '__main__':
49+
sys.exit(test_no_convert_fun_generated())

0 commit comments

Comments
 (0)