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 @@ -10,6 +10,7 @@ Compiler Features:
* Yul EVM Code Transform: Improve stack shuffler performance by fixing a BFS deduplication issue.

Bugfixes:
* Yul IR Code Generation: Fix internal compiler error when emitting an event with an indexed function type parameter that requires implicit conversion.


### 0.8.34 (2026-02-18)
Expand Down
11 changes: 5 additions & 6 deletions libsolidity/codegen/ir/IRGeneratorForStatements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1090,12 +1090,11 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
")\n";
else if (auto functionType = dynamic_cast<FunctionType const*>(paramTypes[i]))
{
solAssert(
IRVariable(arg).type() == *functionType &&
functionType->kind() == FunctionType::Kind::External &&
!functionType->hasBoundFirstArgument(),
""
);
auto const* argFunctionType = dynamic_cast<FunctionType const*>(&IRVariable(arg).type());
solAssert(argFunctionType);
solAssert(argFunctionType->kind() == FunctionType::Kind::External);
solAssert(!argFunctionType->hasBoundFirstArgument());
solAssert(functionType->kind() == FunctionType::Kind::External);
define(indexedArgs.emplace_back(m_context.newYulVariable(), *TypeProvider::fixedBytes(32))) <<
m_utils.combineExternalFunctionIdFunction() <<
"(" <<
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Used to cause ICE in IR codegen when emitting an indexed event parameter
// with an implicitly convertible function type (different state mutability).
contract C {
event ViewEvent(function() external view indexed);
event NonpayableEvent(function() external indexed);

function externalPure() external pure {}
function externalView() external view {}
function externalPayable() external payable {}

// pure -> view
function test_pure_to_view() public {
emit ViewEvent(C(address(0x1234)).externalPure);
}
// pure -> nonpayable
function test_pure_to_nonpayable() public {
emit NonpayableEvent(C(address(0x1234)).externalPure);
}
// view -> nonpayable
function test_view_to_nonpayable() public {
emit NonpayableEvent(C(address(0x1234)).externalView);
}
// payable -> nonpayable
function test_payable_to_nonpayable() public {
emit NonpayableEvent(C(address(0x1234)).externalPayable);
}
}
// ----
// test_pure_to_view() ->
// ~ emit ViewEvent(function): #0x123432de51f20000000000000000
// test_pure_to_nonpayable() ->
// ~ emit NonpayableEvent(function): #0x123432de51f20000000000000000
// test_view_to_nonpayable() ->
// ~ emit NonpayableEvent(function): #0x12347fb3a0c30000000000000000
// test_payable_to_nonpayable() ->
// ~ emit NonpayableEvent(function): #0x12349298fb810000000000000000