Type promotion fixes and tests.

This commit is contained in:
Christian 2014-11-04 21:29:36 +01:00
parent 13baaf98b8
commit 95d2edfbac
2 changed files with 8 additions and 12 deletions

View File

@ -136,15 +136,9 @@ bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation)
cleanupNeeded = true; cleanupNeeded = true;
leftExpression.accept(*this); leftExpression.accept(*this);
if (cleanupNeeded) appendTypeConversion(*leftExpression.getType(), commonType, cleanupNeeded);
appendHighBitsCleanup(dynamic_cast<IntegerType const&>(*leftExpression.getType()));
else
appendTypeConversion(*leftExpression.getType(), commonType);
rightExpression.accept(*this); rightExpression.accept(*this);
if (cleanupNeeded) appendTypeConversion(*rightExpression.getType(), commonType, cleanupNeeded);
appendHighBitsCleanup(dynamic_cast<IntegerType const&>(*leftExpression.getType()));
else
appendTypeConversion(*rightExpression.getType(), commonType);
if (Token::isCompareOp(op)) if (Token::isCompareOp(op))
appendCompareOperatorCode(op, commonType); appendCompareOperatorCode(op, commonType);
else else
@ -368,20 +362,20 @@ void ExpressionCompiler::appendShiftOperatorCode(Token::Value _operator)
} }
} }
void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type const& _targetType) void ExpressionCompiler::appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded)
{ {
// If the type of one of the operands is extended, we need to remove all // If the type of one of the operands is extended, we need to remove all
// higher-order bits that we might have ignored in previous operations. // higher-order bits that we might have ignored in previous operations.
// @todo: store in the AST whether the operand might have "dirty" higher // @todo: store in the AST whether the operand might have "dirty" higher
// order bits // order bits
if (_typeOnStack == _targetType) if (_typeOnStack == _targetType && !_cleanupNeeded)
return; return;
if (_typeOnStack.getCategory() == Type::Category::INTEGER) if (_typeOnStack.getCategory() == Type::Category::INTEGER)
{ {
appendHighBitsCleanup(dynamic_cast<IntegerType const&>(_typeOnStack)); appendHighBitsCleanup(dynamic_cast<IntegerType const&>(_typeOnStack));
} }
else else if (_typeOnStack != _targetType)
{ {
// All other types should not be convertible to non-equal types. // All other types should not be convertible to non-equal types.
assert(!_typeOnStack.isExplicitlyConvertibleTo(_targetType)); assert(!_typeOnStack.isExplicitlyConvertibleTo(_targetType));

View File

@ -66,7 +66,9 @@ private:
/// Appends an implicit or explicit type conversion. For now this comprises only erasing /// Appends an implicit or explicit type conversion. For now this comprises only erasing
/// higher-order bits (@see appendHighBitCleanup) when widening integer types. /// higher-order bits (@see appendHighBitCleanup) when widening integer types.
void appendTypeConversion(Type const& _typeOnStack, Type const& _targetType); /// If @a _cleanupNeeded, high order bits cleanup is also done if no type conversion would be
/// necessary.
void appendTypeConversion(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded = false);
//// Appends code that cleans higher-order bits for integer types. //// Appends code that cleans higher-order bits for integer types.
void appendHighBitsCleanup(IntegerType const& _typeOnStack); void appendHighBitsCleanup(IntegerType const& _typeOnStack);