Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Compiler Features:
* General: Remove support for the experimental EOF (EVM Object Format) backend.

Bugfixes:
* Codegen: Fix uninitialized internal function pointers being read from a packed storage slot with the wrong value when a subsequent variable in the slot holds a non-zero value.
* NatSpec: Disallow `@return` tag in event documentation.
* SMTChecker: Fix incorrect handling of constant operands of unary operations.

Expand Down
4 changes: 4 additions & 0 deletions libsolidity/codegen/LValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ void GenericStorageItem<IsTransient>::retrieveValue(langutil::SourceLocation con
if (type->category() == Type::Category::UserDefinedValueType)
type = type->encodingType();
bool cleaned = false;
// shift bytes to the right positioning the function pointer at the start of the slot
m_context
<< Instruction::SWAP1 << s_loadInstruction << Instruction::SWAP1
<< u256(0x100) << Instruction::EXP << Instruction::SWAP1 << Instruction::DIV;
Expand All @@ -257,9 +258,12 @@ void GenericStorageItem<IsTransient>::retrieveValue(langutil::SourceLocation con
}
else if (fun->kind() == FunctionType::Kind::Internal)
{
// internal function pointers occupy 8 bytes, so we mask the remaining bytes in the slot
m_context << ((u256(0x1) << (8 * type->storageBytes())) - 1) << Instruction::AND;
m_context << Instruction::DUP1 << Instruction::ISZERO;
CompilerUtils(m_context).pushZeroValue(*fun);
m_context << Instruction::MUL << Instruction::OR;
cleaned = true;
}
}
else if (type->leftAligned())
Expand Down
13 changes: 9 additions & 4 deletions test/cmdlineTests/optimizer_inliner_dynamic_reference/output
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,20 @@ sub_0: assembly {
/* "input.sol":295:298 x() */
tag_19
swap1
0xffffffff
/* "input.sol":295:296 x */
dup1
iszero
tag_20
0xffffffffffffffff
dup4
and
iszero
mul
or
/* "input.sol":295:298 x() */
0xffffffff
dup2
and
swap2
and
or
jump // in
tag_19:
/* "input.sol":295:302 x() + 1 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,20 @@ sub_0: assembly {
/* "input.sol":289:292 x() */
tag_16
swap1
0xffffffff
/* "input.sol":289:290 x */
dup1
iszero
tag_17
0xffffffffffffffff
dup4
and
iszero
mul
or
/* "input.sol":289:292 x() */
0xffffffff
dup2
and
swap2
and
or
jump // in
tag_16:
/* "input.sol":289:296 x() + 1 */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ contract C {
// ====
// compileViaYul: false
// ----
// t() -> FAILURE
// t() -> FAILURE, hex"4e487b71", 0x51
// gas legacy: 77534
// gas legacy code: 69600
// gas legacyOptimized: 76677
// gas legacyOptimized code: 28600
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,5 @@ contract C {
// gas irOptimized code: 19000
// gas legacy: 79492
// gas legacy code: 69600
// gas legacyOptimized: 77587
// gas legacyOptimized: 77611
// gas legacyOptimized code: 28600
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
contract C {
uint32 public x = 1;
function() internal internalFunctionPointer;
uint32 private y = 2;

function testComparison() public view returns (bool) {
function() internal uninitializedPointer;
if (internalFunctionPointer == uninitializedPointer)
return true;
return false;
}
function testLocalAssignment() public view returns (bool) {
function() internal uninitializedPointer;
function() internal localPointer = internalFunctionPointer;
if (localPointer == uninitializedPointer)
return true;
return false;
}
}
// ----
// testComparison() -> true
// testLocalAssignment() -> true
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
contract C {
uint32 public transient x;
function() internal transient internalFunctionPointer;
uint32 private transient y;

function testComparison() public returns (bool) {
x = 1;
y = 2;
function() internal uninitializedPointer;
if (internalFunctionPointer == uninitializedPointer)
return true;
return false;
}
function testLocalAssignment() public returns (bool) {
x = 1;
y = 2;
function() internal uninitializedPointer;
function() internal localPointer = internalFunctionPointer;
if (localPointer == uninitializedPointer)
return true;
return false;
}
}
// ====
// EVMVersion: >=cancun
// ----
// testComparison() -> true
// testLocalAssignment() -> true