Skip to content

Commit 22116df

Browse files
Merge pull request #12584 from nishant-sachdeva/indexed_log_topic_differs_between_legacy_and_ir_if_explicitly_downcast
Code generators needed fixing of the cleanup process during typecasting
2 parents b897d5d + dec511a commit 22116df

10 files changed

+81
-17
lines changed

Changelog.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Bugfixes:
1616
* Code Generator: Fix ICE when doing an explicit conversion from ``string calldata`` to ``bytes``.
1717
* Control Flow Graph: Perform proper virtual lookup for modifiers for uninitialized variable and unreachable code analysis.
1818
* Immutables: Fix wrong error when the constructor of a base contract uses ``return`` and the parent contract contains immutable variables.
19+
* IR Generator: Add missing cleanup during the conversion of fixed bytes types to smaller fixed bytes types.
20+
* IR Generator: Add missing cleanup for indexed event arguments of value type.
1921
* IR Generator: Fix IR syntax error when copying storage arrays of structs containing functions.
2022
* Natspec: Fix ICE when overriding a struct getter with a Natspec-documented return value and the name in the struct is different.
2123
* TypeChecker: Fix ICE when a constant variable declaration forward references a struct.

libsolidity/codegen/YulUtilFunctions.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3400,11 +3400,11 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
34003400
.render();
34013401
else
34023402
{
3403-
// clear for conversion to longer bytes
34043403
solAssert(toCategory == Type::Category::FixedBytes, "Invalid type conversion requested.");
3404+
FixedBytesType const& to = dynamic_cast<FixedBytesType const&>(_to);
34053405
body =
34063406
Whiskers("converted := <clean>(value)")
3407-
("clean", cleanupFunction(from))
3407+
("clean", cleanupFunction((to.numBytes() <= from.numBytes()) ? to : from))
34083408
.render();
34093409
}
34103410
break;

libsolidity/codegen/ir/IRGeneratorForStatements.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,7 +1035,10 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
10351035
")\n";
10361036
}
10371037
else
1038-
indexedArgs.emplace_back(convert(arg, *paramTypes[i]));
1038+
{
1039+
solAssert(parameterTypes[i]->sizeOnStack() == 1, "");
1040+
indexedArgs.emplace_back(convert(arg, *paramTypes[i], true));
1041+
}
10391042
}
10401043
else
10411044
{
@@ -2724,14 +2727,14 @@ void IRGeneratorForStatements::assignInternalFunctionIDIfNotCalledDirectly(
27242727
m_context.addToInternalDispatch(_referencedFunction);
27252728
}
27262729

2727-
IRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to)
2730+
IRVariable IRGeneratorForStatements::convert(IRVariable const& _from, Type const& _to, bool _forceCleanup)
27282731
{
2729-
if (_from.type() == _to)
2732+
if (_from.type() == _to && !_forceCleanup)
27302733
return _from;
27312734
else
27322735
{
27332736
IRVariable converted(m_context.newYulVariable(), _to);
2734-
define(converted, _from);
2737+
define(converted, _from, _forceCleanup);
27352738
return converted;
27362739
}
27372740
}
@@ -2763,10 +2766,10 @@ void IRGeneratorForStatements::declare(IRVariable const& _var)
27632766
appendCode() << "let " << _var.commaSeparatedList() << "\n";
27642767
}
27652768

2766-
void IRGeneratorForStatements::declareAssign(IRVariable const& _lhs, IRVariable const& _rhs, bool _declare)
2769+
void IRGeneratorForStatements::declareAssign(IRVariable const& _lhs, IRVariable const& _rhs, bool _declare, bool _forceCleanup)
27672770
{
27682771
string output;
2769-
if (_lhs.type() == _rhs.type())
2772+
if (_lhs.type() == _rhs.type() && !_forceCleanup)
27702773
for (auto const& [stackItemName, stackItemType]: _lhs.type().stackItems())
27712774
if (stackItemType)
27722775
declareAssign(_lhs.part(stackItemName), _rhs.part(stackItemName), _declare);

libsolidity/codegen/ir/IRGeneratorForStatements.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,11 @@ class IRGeneratorForStatements: public IRGeneratorForStatementsBase
8686
IRVariable evaluateExpression(Expression const& _expression, Type const& _to);
8787

8888
/// Defines @a _var using the value of @a _value while performing type conversions, if required.
89-
void define(IRVariable const& _var, IRVariable const& _value) { declareAssign(_var, _value, true); }
89+
/// If @a _forceCleanup is set to true, it also cleans the value of the variable after the conversion.
90+
void define(IRVariable const& _var, IRVariable const& _value, bool _forceCleanup = false)
91+
{
92+
declareAssign(_var, _value, true, _forceCleanup);
93+
}
9094

9195
/// @returns the name of a function that computes the value of the given constant
9296
/// and also generates the function.
@@ -162,8 +166,8 @@ class IRGeneratorForStatements: public IRGeneratorForStatementsBase
162166
);
163167

164168
/// Generates the required conversion code and @returns an IRVariable referring to the value of @a _variable
165-
/// converted to type @a _to.
166-
IRVariable convert(IRVariable const& _variable, Type const& _to);
169+
/// If @a _forceCleanup is set to true, it also cleans the value of the variable after the conversion.
170+
IRVariable convert(IRVariable const& _variable, Type const& _to, bool _forceCleanup = false);
167171

168172
/// @returns a Yul expression representing the current value of @a _expression,
169173
/// converted to type @a _to if it does not yet have that type.
@@ -179,7 +183,7 @@ class IRGeneratorForStatements: public IRGeneratorForStatementsBase
179183
/// Declares variable @a _var.
180184
void declare(IRVariable const& _var);
181185

182-
void declareAssign(IRVariable const& _var, IRVariable const& _value, bool _define);
186+
void declareAssign(IRVariable const& _var, IRVariable const& _value, bool _define, bool _forceCleanup = false);
183187

184188
/// @returns an IRVariable with the zero
185189
/// value of @a _type.

test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening.sol renamed to test/libsolidity/semanticTests/cleanup/cleanup_bytes_types_shortening_OldCodeGen.sol

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ contract C {
1111
}
1212
}
1313
// ====
14-
// compileToEwasm: also
15-
// compileViaYul: also
14+
// compileViaYul: false
1615
// ----
17-
// f() -> "\xff\xff\xff\xff"
16+
// f() -> 0xffffffff00000000000000000000000000000000000000000000000000000000
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
contract C {
2+
function f() public pure returns (bytes32 r) {
3+
bytes4 x = 0xffffffff;
4+
bytes2 y = bytes2(x);
5+
assembly {
6+
r := y
7+
}
8+
}
9+
}
10+
// ====
11+
// compileToEwasm: also
12+
// compileViaYul: true
13+
// ----
14+
// f() -> 0xffff000000000000000000000000000000000000000000000000000000000000
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
contract C {
2+
function f() public pure returns (uint32 y) {
3+
uint8 x = uint8(uint256(0x31313131313131313131313131313131));
4+
assembly { y := x }
5+
}
6+
7+
function g() public pure returns (bytes32 y) {
8+
bytes1 x = bytes1(bytes16(0x31313131313131313131313131313131));
9+
assembly { y := x }
10+
}
11+
12+
function h() external returns (bytes32 y) {
13+
bytes1 x;
14+
assembly { x := sub(0,1) }
15+
y = x;
16+
}
17+
}
18+
// ====
19+
// compileViaYul: true
20+
// ----
21+
// f() -> 0x31
22+
// g() -> 0x3100000000000000000000000000000000000000000000000000000000000000
23+
// h() -> 0xff00000000000000000000000000000000000000000000000000000000000000
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
contract C {
2+
event ev0(bytes1 indexed);
3+
constructor() {
4+
emit ev0(bytes1(bytes16(0x31313131313131313131313131313131)));
5+
}
6+
function j() external {
7+
bytes1 x;
8+
assembly { x := 0x3131313131313131313131313131313131313131313131313131313131313131 }
9+
emit ev0(x);
10+
}
11+
}
12+
// ====
13+
// compileViaYul: also
14+
// ----
15+
// constructor() ->
16+
// ~ emit ev0(bytes1): #"1"
17+
// gas legacy: 168735
18+
// j() ->
19+
// ~ emit ev0(bytes1): #"1"

test/libsolidity/semanticTests/userDefinedValueType/erc20.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ contract ERC20 {
115115
// ----
116116
// constructor()
117117
// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14
118-
// gas irOptimized: 442239
118+
// gas irOptimized: 447831
119119
// gas legacy: 861559
120120
// gas legacyOptimized: 420959
121121
// totalSupply() -> 20

test/libsolidity/semanticTests/various/erc20.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ contract ERC20 {
9898
// ----
9999
// constructor()
100100
// ~ emit Transfer(address,address,uint256): #0x00, #0x1212121212121212121212121212120000000012, 0x14
101-
// gas irOptimized: 437697
101+
// gas irOptimized: 443295
102102
// gas legacy: 833310
103103
// gas legacyOptimized: 416135
104104
// totalSupply() -> 20

0 commit comments

Comments
 (0)