diff --git a/Changelog.md b/Changelog.md index 201d792ed..39ba31c4d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -35,6 +35,7 @@ Bugfixes: * SMTChecker: Fix internal error when implicitly converting string literals to fixed bytes. * Type Checker: Disallow constructor of the same class to be used as modifier. * Type Checker: Treat magic variables as unknown identifiers in inline assembly. + * Code Generator: Fix internal error when trying to convert ``super`` to a different type diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index f5e315829..ccdadc5df 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1433,6 +1433,9 @@ Type const* ContractType::encodingType() const BoolResult ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const { + if (m_super) + return false; + if (*this == _convertTo) return true; if (_convertTo.category() == Category::Contract) @@ -1450,8 +1453,12 @@ BoolResult ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const BoolResult ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const { + if (m_super) + return false; + if (auto const* addressType = dynamic_cast<AddressType const*>(&_convertTo)) return isPayable() || (addressType->stateMutability() < StateMutability::Payable); + return isImplicitlyConvertibleTo(_convertTo); } diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index a275a6e03..5333cfddb 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -711,6 +711,9 @@ void CompilerUtils::convertType( Type::Category stackTypeCategory = _typeOnStack.category(); Type::Category targetTypeCategory = _targetType.category(); + if (auto contrType = dynamic_cast<ContractType const*>(&_typeOnStack)) + solAssert(!contrType->isSuper(), "Cannot convert magic variable \"super\""); + bool enumOverflowCheckPending = (targetTypeCategory == Type::Category::Enum || stackTypeCategory == Type::Category::Enum); bool chopSignBitsPending = _chopSignBits && targetTypeCategory == Type::Category::Integer; if (chopSignBitsPending) diff --git a/test/libsolidity/syntaxTests/conversion/not_allowed_conversion_from_super.sol b/test/libsolidity/syntaxTests/conversion/not_allowed_conversion_from_super.sol new file mode 100644 index 000000000..dc6f00f43 --- /dev/null +++ b/test/libsolidity/syntaxTests/conversion/not_allowed_conversion_from_super.sol @@ -0,0 +1,15 @@ +contract S +{ + int o; + function foo() public returns (int) { return o = 3; } +} + +contract B is S +{ + function fii() public + { + o = S(super).foo(); + } +} +// ---- +// TypeError: (129-137): Explicit type conversion not allowed from "contract super B" to "contract S".