| 756 | } |
| 757 | |
| 758 | void CompilerUtils::convertType( |
| 759 | Type const& _typeOnStack, |
| 760 | Type const& _targetType, |
| 761 | bool _cleanupNeeded, |
| 762 | bool _chopSignBits, |
| 763 | bool _asPartOfArgumentDecoding |
| 764 | ) |
| 765 | { |
| 766 | // For a type extension, we need to remove all higher-order bits that we might have ignored in |
| 767 | // previous operations. |
| 768 | // @todo: store in the AST whether the operand might have "dirty" higher order bits |
| 769 | |
| 770 | if (_typeOnStack == _targetType && !_cleanupNeeded) |
| 771 | return; |
| 772 | Type::Category stackTypeCategory = _typeOnStack.category(); |
| 773 | Type::Category targetTypeCategory = _targetType.category(); |
| 774 | |
| 775 | if (stackTypeCategory == Type::Category::UserDefinedValueType) |
| 776 | { |
| 777 | solAssert(_cleanupNeeded); |
| 778 | auto& userDefined = dynamic_cast<UserDefinedValueType const&>(_typeOnStack); |
| 779 | solAssert(_typeOnStack == _targetType || _targetType == userDefined.underlyingType()); |
| 780 | return convertType( |
| 781 | userDefined.underlyingType(), |
| 782 | _targetType, |
| 783 | _cleanupNeeded, |
| 784 | _chopSignBits, |
| 785 | _asPartOfArgumentDecoding |
| 786 | ); |
| 787 | } |
| 788 | if (targetTypeCategory == Type::Category::UserDefinedValueType) |
| 789 | { |
| 790 | solAssert(_cleanupNeeded); |
| 791 | auto& userDefined = dynamic_cast<UserDefinedValueType const&>(_targetType); |
| 792 | solAssert(_typeOnStack.isImplicitlyConvertibleTo(userDefined.underlyingType())); |
| 793 | return convertType( |
| 794 | _typeOnStack, |
| 795 | userDefined.underlyingType(), |
| 796 | _cleanupNeeded, |
| 797 | _chopSignBits, |
| 798 | _asPartOfArgumentDecoding |
| 799 | ); |
| 800 | } |
| 801 | |
| 802 | if (auto contrType = dynamic_cast<ContractType const*>(&_typeOnStack)) |
| 803 | solAssert(!contrType->isSuper(), "Cannot convert magic variable \"super\""); |
| 804 | |
| 805 | bool enumOverflowCheckPending = (targetTypeCategory == Type::Category::Enum || stackTypeCategory == Type::Category::Enum); |
| 806 | bool chopSignBitsPending = _chopSignBits && targetTypeCategory == Type::Category::Integer; |
| 807 | if (chopSignBitsPending) |
| 808 | { |
| 809 | IntegerType const& targetIntegerType = dynamic_cast<IntegerType const&>(_targetType); |
| 810 | chopSignBitsPending = targetIntegerType.isSigned(); |
| 811 | } |
| 812 | |
| 813 | if (targetTypeCategory == Type::Category::FixedPoint) |
| 814 | solUnimplemented("Not yet implemented - FixedPointType."); |
| 815 |
no test coverage detected