mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix assertion preventing assignment of arrays of implicitly convertible function types
This commit is contained in:
parent
3c350a63f1
commit
ccf658b0e8
@ -16,6 +16,7 @@ Compiler Features:
|
|||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* AST: Do not output value of Yul literal if it is not a valid UTF-8 string.
|
* AST: Do not output value of Yul literal if it is not a valid UTF-8 string.
|
||||||
|
* Code Generator: Fix internal error when function arrays are assigned to storage variables and the function types can be implicitly converted but are not identical.
|
||||||
* Code Generator: Fix internal error when super would have to skip an unimplemented function in the virtual resolution order.
|
* Code Generator: Fix internal error when super would have to skip an unimplemented function in the virtual resolution order.
|
||||||
* Control Flow Graph: Take internal calls to functions that always revert into account for reporting unused or unassigned variables.
|
* Control Flow Graph: Take internal calls to functions that always revert into account for reporting unused or unassigned variables.
|
||||||
* SMTChecker: Fix internal error on struct constructor with fixed bytes member initialized with string literal.
|
* SMTChecker: Fix internal error on struct constructor with fixed bytes member initialized with string literal.
|
||||||
|
@ -300,16 +300,26 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
|
|||||||
// stack: value storage_ref cleared_value multiplier
|
// stack: value storage_ref cleared_value multiplier
|
||||||
utils.copyToStackTop(3 + m_dataType->sizeOnStack(), m_dataType->sizeOnStack());
|
utils.copyToStackTop(3 + m_dataType->sizeOnStack(), m_dataType->sizeOnStack());
|
||||||
// stack: value storage_ref cleared_value multiplier value
|
// stack: value storage_ref cleared_value multiplier value
|
||||||
if (FunctionType const* fun = dynamic_cast<decltype(fun)>(m_dataType))
|
if (auto const* fun = dynamic_cast<FunctionType const*>(m_dataType))
|
||||||
{
|
{
|
||||||
solAssert(_sourceType == *m_dataType, "function item stored but target is not equal to source");
|
solAssert(
|
||||||
|
_sourceType.isImplicitlyConvertibleTo(*m_dataType),
|
||||||
|
"function item stored but target is not implicitly convertible to source"
|
||||||
|
);
|
||||||
|
solAssert(!fun->bound(), "");
|
||||||
if (fun->kind() == FunctionType::Kind::External)
|
if (fun->kind() == FunctionType::Kind::External)
|
||||||
|
{
|
||||||
|
solAssert(fun->sizeOnStack() == 2, "");
|
||||||
// Combine the two-item function type into a single stack slot.
|
// Combine the two-item function type into a single stack slot.
|
||||||
utils.combineExternalFunctionType(false);
|
utils.combineExternalFunctionType(false);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
solAssert(fun->sizeOnStack() == 1, "");
|
||||||
m_context <<
|
m_context <<
|
||||||
((u256(1) << (8 * m_dataType->storageBytes())) - 1) <<
|
((u256(1) << (8 * m_dataType->storageBytes())) - 1) <<
|
||||||
Instruction::AND;
|
Instruction::AND;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (m_dataType->category() == Type::Category::FixedBytes)
|
else if (m_dataType->category() == Type::Category::FixedBytes)
|
||||||
{
|
{
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
contract C {
|
||||||
|
function () external returns(uint)[1] externalDefaultArray;
|
||||||
|
function () external view returns(uint)[1] externalViewArray;
|
||||||
|
function () external pure returns(uint)[1] externalPureArray;
|
||||||
|
|
||||||
|
function () internal returns(uint)[1] internalDefaultArray;
|
||||||
|
function () internal view returns(uint)[1] internalViewArray;
|
||||||
|
function () internal pure returns(uint)[1] internalPureArray;
|
||||||
|
|
||||||
|
function externalDefault() external returns(uint) { return 11; }
|
||||||
|
function externalView() external view returns(uint) { return 12; }
|
||||||
|
function externalPure() external pure returns(uint) { return 13; }
|
||||||
|
|
||||||
|
function internalDefault() internal returns(uint) { return 21; }
|
||||||
|
function internalView() internal view returns(uint) { return 22; }
|
||||||
|
function internalPure() internal pure returns(uint) { return 23; }
|
||||||
|
|
||||||
|
function testViewToDefault() public returns (uint, uint) {
|
||||||
|
externalDefaultArray = [this.externalView];
|
||||||
|
internalDefaultArray = [internalView];
|
||||||
|
|
||||||
|
return (externalDefaultArray[0](), internalDefaultArray[0]());
|
||||||
|
}
|
||||||
|
|
||||||
|
function testPureToDefault() public returns (uint, uint) {
|
||||||
|
externalDefaultArray = [this.externalPure];
|
||||||
|
internalDefaultArray = [internalPure];
|
||||||
|
|
||||||
|
return (externalDefaultArray[0](), internalDefaultArray[0]());
|
||||||
|
}
|
||||||
|
|
||||||
|
function testPureToView() public returns (uint, uint) {
|
||||||
|
externalViewArray = [this.externalPure];
|
||||||
|
internalViewArray = [internalPure];
|
||||||
|
|
||||||
|
return (externalViewArray[0](), internalViewArray[0]());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ====
|
||||||
|
// compileViaYul: also
|
||||||
|
// ----
|
||||||
|
// testViewToDefault() -> 12, 22
|
||||||
|
// testPureToDefault() -> 13, 23
|
||||||
|
// testPureToView() -> 13, 23
|
@ -0,0 +1,49 @@
|
|||||||
|
contract C {
|
||||||
|
function externalDefault() external returns(uint) { return 11; }
|
||||||
|
function externalView() external view returns(uint) { return 12; }
|
||||||
|
function externalPure() external pure returns(uint) { return 13; }
|
||||||
|
|
||||||
|
function internalDefault() internal returns(uint) { return 21; }
|
||||||
|
function internalView() internal view returns(uint) { return 22; }
|
||||||
|
function internalPure() internal pure returns(uint) { return 23; }
|
||||||
|
|
||||||
|
function testViewToDefault() public returns (uint, uint) {
|
||||||
|
function () external returns(uint)[1] memory externalDefaultArray;
|
||||||
|
function () internal returns(uint)[1] memory internalDefaultArray;
|
||||||
|
|
||||||
|
// This would work if we were assigning to storage rather than memory
|
||||||
|
externalDefaultArray = [this.externalView];
|
||||||
|
internalDefaultArray = [internalView];
|
||||||
|
|
||||||
|
return (externalDefaultArray[0](), internalDefaultArray[0]());
|
||||||
|
}
|
||||||
|
|
||||||
|
function testPureToDefault() public returns (uint, uint) {
|
||||||
|
function () external returns(uint)[1] memory externalDefaultArray;
|
||||||
|
function () internal returns(uint)[1] memory internalDefaultArray;
|
||||||
|
|
||||||
|
// This would work if we were assigning to storage rather than memory
|
||||||
|
externalDefaultArray = [this.externalPure];
|
||||||
|
internalDefaultArray = [internalPure];
|
||||||
|
|
||||||
|
return (externalDefaultArray[0](), internalDefaultArray[0]());
|
||||||
|
}
|
||||||
|
|
||||||
|
function testPureToView() public returns (uint, uint) {
|
||||||
|
function () external returns(uint)[1] memory externalViewArray;
|
||||||
|
function () internal returns(uint)[1] memory internalViewArray;
|
||||||
|
|
||||||
|
// This would work if we were assigning to storage rather than memory
|
||||||
|
externalViewArray = [this.externalPure];
|
||||||
|
internalViewArray = [internalPure];
|
||||||
|
|
||||||
|
return (externalViewArray[0](), internalViewArray[0]());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 7407: (760-779): Type function () view external returns (uint256)[1] memory is not implicitly convertible to expected type function () external returns (uint256)[1] memory.
|
||||||
|
// TypeError 7407: (812-826): Type function () view returns (uint256)[1] memory is not implicitly convertible to expected type function () returns (uint256)[1] memory.
|
||||||
|
// TypeError 7407: (1230-1249): Type function () pure external returns (uint256)[1] memory is not implicitly convertible to expected type function () external returns (uint256)[1] memory.
|
||||||
|
// TypeError 7407: (1282-1296): Type function () pure returns (uint256)[1] memory is not implicitly convertible to expected type function () returns (uint256)[1] memory.
|
||||||
|
// TypeError 7407: (1688-1707): Type function () pure external returns (uint256)[1] memory is not implicitly convertible to expected type function () external returns (uint256)[1] memory.
|
||||||
|
// TypeError 7407: (1737-1751): Type function () pure returns (uint256)[1] memory is not implicitly convertible to expected type function () returns (uint256)[1] memory.
|
Loading…
Reference in New Issue
Block a user