From d7b4b4a7aae7066709ad67144bc6e8ff0482460e Mon Sep 17 00:00:00 2001 From: a3d4 Date: Tue, 6 Oct 2020 20:58:46 +0200 Subject: [PATCH] Fix ICE caused by storage parameters with nested mappings in libraries --- Changelog.md | 9 +++++++++ libsolidity/analysis/TypeChecker.cpp | 9 +++++++-- .../mapping/contract_storage_parameter_with_mapping.sol | 6 ++++++ .../mapping/library_storage_parameter_with_mapping.sol | 4 ++++ .../library_storage_parameter_with_nested_mapping.sol | 5 +++++ 5 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 test/libsolidity/syntaxTests/types/mapping/contract_storage_parameter_with_mapping.sol create mode 100644 test/libsolidity/syntaxTests/types/mapping/library_storage_parameter_with_mapping.sol create mode 100644 test/libsolidity/syntaxTests/types/mapping/library_storage_parameter_with_nested_mapping.sol diff --git a/Changelog.md b/Changelog.md index bc5de019b..7f1c67052 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,14 @@ ### 0.7.4 (unreleased) +Important Bugfixes: + + +Compiler Features: + + +Bugfixes: + * Type Checker: Fix internal compiler error caused by storage parameters with nested mappings in libraries. + ### 0.7.3 (2020-10-07) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 8ed904129..46d7b6e61 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -599,8 +599,13 @@ bool TypeChecker::visit(VariableDeclaration const& _variable) if (auto referenceType = dynamic_cast(varType)) { auto result = referenceType->validForLocation(referenceType->location()); - if (result && (_variable.isConstructorParameter() || _variable.isPublicCallableParameter())) - result = referenceType->validForLocation(DataLocation::CallData); + if (result) + { + bool isLibraryStorageParameter = (_variable.isLibraryFunctionParameter() && referenceType->location() == DataLocation::Storage); + bool callDataCheckRequired = ((_variable.isConstructorParameter() || _variable.isPublicCallableParameter()) && !isLibraryStorageParameter); + if (callDataCheckRequired) + result = referenceType->validForLocation(DataLocation::CallData); + } if (!result) { solAssert(!result.message().empty(), "Expected detailed error message"); diff --git a/test/libsolidity/syntaxTests/types/mapping/contract_storage_parameter_with_mapping.sol b/test/libsolidity/syntaxTests/types/mapping/contract_storage_parameter_with_mapping.sol new file mode 100644 index 000000000..5e33008ba --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/contract_storage_parameter_with_mapping.sol @@ -0,0 +1,6 @@ +struct S { mapping(uint => uint)[2] a; } +contract C { + function f(S storage s) public {} +} +// ---- +// TypeError 6651: (69-80): Data location must be "memory" or "calldata" for parameter in function, but "storage" was given. diff --git a/test/libsolidity/syntaxTests/types/mapping/library_storage_parameter_with_mapping.sol b/test/libsolidity/syntaxTests/types/mapping/library_storage_parameter_with_mapping.sol new file mode 100644 index 000000000..a8ee8a3e3 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_storage_parameter_with_mapping.sol @@ -0,0 +1,4 @@ +struct S { mapping(uint => uint)[2] a; } +library L { + function f(S storage s) public {} +} diff --git a/test/libsolidity/syntaxTests/types/mapping/library_storage_parameter_with_nested_mapping.sol b/test/libsolidity/syntaxTests/types/mapping/library_storage_parameter_with_nested_mapping.sol new file mode 100644 index 000000000..9c4579874 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/mapping/library_storage_parameter_with_nested_mapping.sol @@ -0,0 +1,5 @@ +library Test { + struct Nested { mapping(uint => uint)[2][] a; } + struct X { Nested n; } + function f(X storage x) public {} +}