From 1d47919c0c77f23542f62f3e4cab83b264d06fa4 Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Wed, 28 Nov 2018 16:16:02 +0100 Subject: [PATCH] Fix ICE when function type struct parameter has field of non-existent type --- Changelog.md | 1 + libsolidity/ast/Types.cpp | 8 +++++++- .../functionTypes/function_type_struct.sol | 8 ++++++++ .../function_type_struct_undefined_member.sol | 11 +++++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/functionTypes/function_type_struct.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/function_type_struct_undefined_member.sol diff --git a/Changelog.md b/Changelog.md index b67bc5928..f64ae1845 100644 --- a/Changelog.md +++ b/Changelog.md @@ -21,6 +21,7 @@ Bugfixes: * Optimizer: Fix nondeterminism bug related to the boost version and constants representation. The bug only resulted in less optimal but still correct code because the generated routine is always verified to be correct. * Type Checker: Properly detect different return types when overriding an external interface function with a public contract function. * Type Checker: Disallow struct return types for getters of public state variables unless the new ABI encoder is active. + * Type Checker: Fix internal compiler error when a field of a struct used as a parameter in a function type has a non-existent type. Build System: * Emscripten: Upgrade to Emscripten SDK 1.37.21 and boost 1.67. diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 102e43e9a..16e9cf892 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2124,9 +2124,15 @@ bool StructType::canBeUsedExternally(bool _inLibrary) const // We pass "false" to canBeUsedExternally (_inLibrary), because this struct will be // passed by value and thus the encoding does not differ, but it will disallow // mappings. + // Also return false 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, + // which is reported as an error. for (auto const& var: m_struct.members()) { - solAssert(var->annotation().type, ""); + // If the struct member does not have a type return false. + // A TypeError is expected in this case. + if (!var->annotation().type) + return false; if (!var->annotation().type->canBeUsedExternally(false)) return false; } diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_struct.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_struct.sol new file mode 100644 index 000000000..a367996e5 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_struct.sol @@ -0,0 +1,8 @@ +library L +{ + struct Nested + { + uint y; + } + function f(function(Nested memory) external) external pure {} +} diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_struct_undefined_member.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_struct_undefined_member.sol new file mode 100644 index 000000000..ca08afe5b --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_struct_undefined_member.sol @@ -0,0 +1,11 @@ +library L +{ + struct Nested + { + Non y; + } + function f(function(Nested memory) external) external pure {} +} +// ---- +// DeclarationError: (32-35): Identifier not found or not unique. +// TypeError: (63-76): Internal type cannot be used for external function type.