aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--libsolidity/ast/Types.cpp8
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_struct.sol8
-rw-r--r--test/libsolidity/syntaxTests/functionTypes/function_type_struct_undefined_member.sol11
4 files changed, 27 insertions, 1 deletions
diff --git a/Changelog.md b/Changelog.md
index b67bc592..f64ae184 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 102e43e9..16e9cf89 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 00000000..a367996e
--- /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 00000000..ca08afe5
--- /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.