diff --git a/Changelog.md b/Changelog.md index 86787337e..763312b52 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ Bugfixes: * Code generator: Defensively pad allocation of creationCode and runtimeCode to multiples of 32 bytes. * Parser: Disallow empty import statements. + * Type Checker: Dissallow mappings with data locations other than 'storage' * Type system: Properly report packed encoded size for arrays and structs (mostly unused until now). diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 6d887c454..b5b7d9152 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -334,10 +334,17 @@ bool TypeChecker::visit(FunctionDefinition const& _function) auto checkArgumentAndReturnParameter = [&](VariableDeclaration const& var) { if (type(var)->category() == Type::Category::Mapping) { - if (!type(var)->dataStoredIn(DataLocation::Storage)) - m_errorReporter.typeError(var.location(), "Mapping types can only have a data location of \"storage\"." ); - else if (!isLibraryFunction && _function.isPublic()) - m_errorReporter.typeError(var.location(), "Mapping types for parameters or return variables can only be used in internal or library functions."); + if (var.referenceLocation() != VariableDeclaration::Location::Storage) + { + if (!isLibraryFunction && _function.isPublic()) + m_errorReporter.typeError(var.location(), "Mapping types can only have a data location of \"storage\" and thus only be parameters or return variables for internal or library functions."); + else + m_errorReporter.typeError(var.location(), "Mapping types can only have a data location of \"storage\"." ); + } + else + { + solAssert(isLibraryFunction || !_function.isPublic(), "Mapping types for parameters or return variables can only be used in internal or library functions."); + } } else { diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol index fa3757fa6..d4a7b4599 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_external.sol @@ -2,5 +2,5 @@ contract c { function f1(mapping(uint => uint) calldata) pure external returns (mapping(uint => uint) memory) {} } // ---- -// TypeError: (29-59): Mapping types for parameters or return variables can only be used in internal or library functions. -// TypeError: (84-112): Mapping types for parameters or return variables can only be used in internal or library functions. +// TypeError: (29-59): Mapping types can only have a data location of "storage" and thus only be parameters or return variables for internal or library functions. +// TypeError: (84-112): Mapping types can only have a data location of "storage" and thus only be parameters or return variables for internal or library functions. diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_internal.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_internal.sol index 17f2f7128..58c105e86 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_internal.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_internal.sol @@ -1,4 +1,6 @@ contract c { - function f4(mapping(uint => uint) memory) pure internal {} + function f4(mapping(uint => uint) storage) pure internal {} + function f5(mapping(uint => uint) memory) pure internal {} } // ---- +// TypeError: (93-121): Mapping types can only have a data location of "storage". diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol index 8c73b5ae9..04932d48a 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_data_location_function_param_public.sol @@ -2,4 +2,4 @@ contract c { function f3(mapping(uint => uint) memory) view public {} } // ---- -// TypeError: (29-57): Mapping types for parameters or return variables can only be used in internal or library functions. +// TypeError: (29-57): Mapping types can only have a data location of "storage" and thus only be parameters or return variables for internal or library functions. diff --git a/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol b/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol index 7378324a7..cf0c67429 100644 --- a/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol +++ b/test/libsolidity/syntaxTests/types/mapping/mapping_return_public_memory.sol @@ -3,4 +3,4 @@ contract C { } } // ---- -// TypeError: (51-79): Mapping types for parameters or return variables can only be used in internal or library functions. +// TypeError: (51-79): Mapping types can only have a data location of "storage" and thus only be parameters or return variables for internal or library functions.