Skip to content

Commit dec511a

Browse files
Corresponding code in the .cpp file has been commented instead of begin removed pending preliminary reviews
Code generators needed fixing of the cleanup process during typecasting of bytes and integers
1 parent b897d5d commit dec511a

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)