diff --git a/Changelog.md b/Changelog.md index ddfe1648e..586217b4f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,7 @@ Compiler Features: * SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions. * Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``. * Standard JSON: Add ``settings.debug.debugInfo`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code. + * Type Checker: Fix internal error about forward-references of user defined value types. Bugfixes: diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index b015939e2..4dec38318 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -150,18 +150,6 @@ void DeclarationTypeChecker::endVisit(UserDefinedValueTypeDefinition const& _use typeName->location(), "The underlying type for a user defined value type has to be an elementary value type." ); - - Type const* type = typeName->annotation().type; - solAssert(type, ""); - solAssert(!dynamic_cast(type), ""); - if (!type->isValueType()) - m_errorReporter.typeError( - 8129_error, - _userDefined.location(), - "The underlying type of the user defined value type \"" + - _userDefined.name() + - "\" is not a value type." - ); } void DeclarationTypeChecker::endVisit(UserDefinedTypeName const& _typeName) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index f11756b25..2f943c4a9 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -338,6 +338,22 @@ void TypeChecker::endVisit(ModifierDefinition const& _modifier) m_errorReporter.typeError(8063_error, _modifier.location(), "Modifiers without implementation must be marked virtual."); } +void TypeChecker::endVisit(UserDefinedValueTypeDefinition const& _userDefined) +{ + solAssert(_userDefined.underlyingType()); + Type const* underlyingType = _userDefined.underlyingType()->annotation().type; + solAssert(underlyingType, ""); + solAssert(!dynamic_cast(underlyingType), ""); + if (!underlyingType->isValueType()) + m_errorReporter.typeError( + 8129_error, + _userDefined.location(), + "The underlying type of the user defined value type \"" + + _userDefined.name() + + "\" is not a value type." + ); +} + bool TypeChecker::visit(FunctionDefinition const& _function) { if (_function.markedVirtual()) diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index bf5039204..989fb857e 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -118,6 +118,7 @@ private: void endVisit(InheritanceSpecifier const& _inheritance) override; void endVisit(ModifierDefinition const& _modifier) override; + void endVisit(UserDefinedValueTypeDefinition const& _userDefined) override; bool visit(FunctionDefinition const& _function) override; bool visit(VariableDeclaration const& _variable) override; /// We need to do this manually because we want to pass the bases of the current contract in