mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Move mapping key checks to ReferencesResolver and make them fatal.
This commit is contained in:
parent
5214cb0e76
commit
9c3151748e
@ -224,15 +224,36 @@ void ReferencesResolver::endVisit(FunctionTypeName const& _typeName)
|
||||
_typeName.annotation().type = TypeProvider::function(_typeName);
|
||||
}
|
||||
|
||||
void ReferencesResolver::endVisit(Mapping const& _typeName)
|
||||
void ReferencesResolver::endVisit(Mapping const& _mapping)
|
||||
{
|
||||
TypePointer keyType = _typeName.keyType().annotation().type;
|
||||
TypePointer valueType = _typeName.valueType().annotation().type;
|
||||
if (auto const* typeName = dynamic_cast<UserDefinedTypeName const*>(&_mapping.keyType()))
|
||||
{
|
||||
if (auto const* contractType = dynamic_cast<ContractType const*>(typeName->annotation().type))
|
||||
{
|
||||
if (contractType->contractDefinition().isLibrary())
|
||||
m_errorReporter.fatalTypeError(
|
||||
typeName->location(),
|
||||
"Library types cannot be used as mapping keys."
|
||||
);
|
||||
}
|
||||
else if (typeName->annotation().type->category() != Type::Category::Enum)
|
||||
m_errorReporter.fatalTypeError(
|
||||
typeName->location(),
|
||||
"Only elementary types, contract types or enums are allowed as mapping keys."
|
||||
);
|
||||
}
|
||||
else
|
||||
solAssert(dynamic_cast<ElementaryTypeName const*>(&_mapping.keyType()), "");
|
||||
|
||||
TypePointer keyType = _mapping.keyType().annotation().type;
|
||||
TypePointer valueType = _mapping.valueType().annotation().type;
|
||||
|
||||
// Convert key type to memory.
|
||||
keyType = TypeProvider::withLocationIfReference(DataLocation::Memory, keyType);
|
||||
|
||||
// Convert value type to storage reference.
|
||||
valueType = TypeProvider::withLocationIfReference(DataLocation::Storage, valueType);
|
||||
_typeName.annotation().type = TypeProvider::mapping(keyType, valueType);
|
||||
_mapping.annotation().type = TypeProvider::mapping(keyType, valueType);
|
||||
}
|
||||
|
||||
void ReferencesResolver::endVisit(ArrayTypeName const& _typeName)
|
||||
|
@ -81,7 +81,7 @@ private:
|
||||
void endVisit(ModifierDefinition const& _modifierDefinition) override;
|
||||
void endVisit(UserDefinedTypeName const& _typeName) override;
|
||||
void endVisit(FunctionTypeName const& _typeName) override;
|
||||
void endVisit(Mapping const& _typeName) override;
|
||||
void endVisit(Mapping const& _mapping) override;
|
||||
void endVisit(ArrayTypeName const& _typeName) override;
|
||||
bool visit(InlineAssembly const& _inlineAssembly) override;
|
||||
bool visit(Return const& _return) override;
|
||||
|
@ -2876,30 +2876,6 @@ void TypeChecker::endVisit(Literal const& _literal)
|
||||
_literal.annotation().isPure = true;
|
||||
}
|
||||
|
||||
bool TypeChecker::visit(Mapping const& _mapping)
|
||||
{
|
||||
if (auto const* keyType = dynamic_cast<UserDefinedTypeName const*>(&_mapping.keyType()))
|
||||
{
|
||||
if (auto const* contractType = dynamic_cast<ContractType const*>(keyType->annotation().type))
|
||||
{
|
||||
if (contractType->contractDefinition().isLibrary())
|
||||
m_errorReporter.typeError(
|
||||
keyType->location(),
|
||||
"Library types cannot be used as mapping keys."
|
||||
);
|
||||
}
|
||||
else if (keyType->annotation().type->category() != Type::Category::Enum)
|
||||
m_errorReporter.typeError(
|
||||
keyType->location(),
|
||||
"Only elementary types, contract types or enums are allowed as mapping keys."
|
||||
);
|
||||
}
|
||||
else
|
||||
solAssert(dynamic_cast<ElementaryTypeName const*>(&_mapping.keyType()), "");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool TypeChecker::contractDependenciesAreCyclic(
|
||||
ContractDefinition const& _contract,
|
||||
std::set<ContractDefinition const*> const& _seenContracts
|
||||
|
@ -143,7 +143,6 @@ private:
|
||||
bool visit(Identifier const& _identifier) override;
|
||||
void endVisit(ElementaryTypeNameExpression const& _expr) override;
|
||||
void endVisit(Literal const& _literal) override;
|
||||
bool visit(Mapping const& _mapping) override;
|
||||
|
||||
bool contractDependenciesAreCyclic(
|
||||
ContractDefinition const& _contract,
|
||||
|
@ -0,0 +1,9 @@
|
||||
// Used to segfault.
|
||||
contract C {
|
||||
struct S {
|
||||
mapping(S => uint) a;
|
||||
}
|
||||
function g (S calldata) external view {}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (56-57): Only elementary types, contract types or enums are allowed as mapping keys.
|
Loading…
Reference in New Issue
Block a user