mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #9686 from ethereum/fix-infinite-loop
Fix infinite loop
This commit is contained in:
commit
e5b9a33998
@ -22,6 +22,7 @@ Bugfixes:
|
|||||||
* Yul Optimizer: Make function inlining order more resilient to whether or not unrelated source files are present.
|
* Yul Optimizer: Make function inlining order more resilient to whether or not unrelated source files are present.
|
||||||
* Type Checker: Disallow signed literals as exponent in exponentiation operator.
|
* Type Checker: Disallow signed literals as exponent in exponentiation operator.
|
||||||
* Allow `type(Contract).name` for abstract contracts and interfaces.
|
* Allow `type(Contract).name` for abstract contracts and interfaces.
|
||||||
|
* Type Checker: Disallow structs containing nested mapping in memory as parameters for library functions.
|
||||||
|
|
||||||
|
|
||||||
### 0.7.0 (2020-07-28)
|
### 0.7.0 (2020-07-28)
|
||||||
|
@ -2463,9 +2463,16 @@ TypeResult StructType::interfaceType(bool _inLibrary) const
|
|||||||
|
|
||||||
TypeResult result{TypePointer{}};
|
TypeResult result{TypePointer{}};
|
||||||
|
|
||||||
|
if (recursive() && !(_inLibrary && location() == DataLocation::Storage))
|
||||||
|
return TypeResult::err(
|
||||||
|
"Recursive structs can only be passed as storage pointers to libraries, "
|
||||||
|
"not as memory objects to contract functions."
|
||||||
|
);
|
||||||
|
|
||||||
util::BreadthFirstSearch<StructDefinition const*> breadthFirstSearch{{&m_struct}};
|
util::BreadthFirstSearch<StructDefinition const*> breadthFirstSearch{{&m_struct}};
|
||||||
breadthFirstSearch.run(
|
breadthFirstSearch.run(
|
||||||
[&](StructDefinition const* _struct, auto&& _addChild) {
|
[&](StructDefinition const* _struct, auto&& _addChild)
|
||||||
|
{
|
||||||
// Check that all members have interface types.
|
// Check that all members have interface types.
|
||||||
// Return an error if at least one struct member does not have a type.
|
// Return an error if at least one struct member does not have a type.
|
||||||
// This might happen, for example, if the type of the member does not exist.
|
// This might happen, for example, if the type of the member does not exist.
|
||||||
@ -2482,22 +2489,19 @@ TypeResult StructType::interfaceType(bool _inLibrary) const
|
|||||||
|
|
||||||
Type const* memberType = variable->annotation().type;
|
Type const* memberType = variable->annotation().type;
|
||||||
|
|
||||||
while (dynamic_cast<ArrayType const*>(memberType))
|
while (
|
||||||
memberType = dynamic_cast<ArrayType const*>(memberType)->baseType();
|
memberType->category() == Type::Category::Array ||
|
||||||
|
memberType->category() == Type::Category::Mapping
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (auto arrayType = dynamic_cast<ArrayType const*>(memberType))
|
||||||
|
memberType = arrayType->finalBaseType(false);
|
||||||
|
else if (auto mappingType = dynamic_cast<MappingType const*>(memberType))
|
||||||
|
memberType = mappingType->valueType();
|
||||||
|
}
|
||||||
|
|
||||||
if (StructType const* innerStruct = dynamic_cast<StructType const*>(memberType))
|
if (StructType const* innerStruct = dynamic_cast<StructType const*>(memberType))
|
||||||
{
|
|
||||||
if (innerStruct->recursive() && !(_inLibrary && location() == DataLocation::Storage))
|
|
||||||
{
|
|
||||||
result = TypeResult::err(
|
|
||||||
"Recursive structs can only be passed as storage pointers to libraries, not as memory objects to contract functions."
|
|
||||||
);
|
|
||||||
breadthFirstSearch.abort();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_addChild(&innerStruct->structDefinition());
|
_addChild(&innerStruct->structDefinition());
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto iType = memberType->interfaceType(_inLibrary);
|
auto iType = memberType->interfaceType(_inLibrary);
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
library a {
|
||||||
|
struct b {
|
||||||
|
mapping (uint => b) c ;
|
||||||
|
}
|
||||||
|
// Segfaults in https://github.com/ethereum/solidity/issues/9443
|
||||||
|
function d(b memory) public {}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 4103: (149-157): Recursive structs can only be passed as storage pointers to libraries, not as memory objects to contract functions.
|
||||||
|
// TypeError 4061: (149-157): Type struct a.b is only valid in storage because it contains a (nested) mapping.
|
@ -0,0 +1,6 @@
|
|||||||
|
library a {
|
||||||
|
struct b {
|
||||||
|
mapping (uint => b) c ;
|
||||||
|
}
|
||||||
|
function d(b storage) public {}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user