From 95d2edfbac4dff62ac987a9fe0fc58fbce76e5b7 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 4 Nov 2014 21:29:36 +0100 Subject: [PATCH] Type promotion fixes and tests. --- ExpressionCompiler.cpp | 16 +++++----------- ExpressionCompiler.h | 4 +++- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index 0df741843..324cd10d0 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -136,15 +136,9 @@ bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation) cleanupNeeded = true; leftExpression.accept(*this); - if (cleanupNeeded) - appendHighBitsCleanup(dynamic_cast(*leftExpression.getType())); - else - appendTypeConversion(*leftExpression.getType(), commonType); + appendTypeConversion(*leftExpression.getType(), commonType, cleanupNeeded); rightExpression.accept(*this); - if (cleanupNeeded) - appendHighBitsCleanup(dynamic_cast(*leftExpression.getType())); - else - appendTypeConversion(*rightExpression.getType(), commonType); + appendTypeConversion(*rightExpression.getType(), commonType, cleanupNeeded); if (Token::isCompareOp(op)) appendCompareOperatorCode(op, commonType); 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 // higher-order bits that we might have ignored in previous operations. // @todo: store in the AST whether the operand might have "dirty" higher // order bits - if (_typeOnStack == _targetType) + if (_typeOnStack == _targetType && !_cleanupNeeded) return; if (_typeOnStack.getCategory() == Type::Category::INTEGER) { appendHighBitsCleanup(dynamic_cast(_typeOnStack)); } - else + else if (_typeOnStack != _targetType) { // All other types should not be convertible to non-equal types. assert(!_typeOnStack.isExplicitlyConvertibleTo(_targetType)); diff --git a/ExpressionCompiler.h b/ExpressionCompiler.h index 7c731ec7f..d67814be0 100644 --- a/ExpressionCompiler.h +++ b/ExpressionCompiler.h @@ -66,7 +66,9 @@ private: /// Appends an implicit or explicit type conversion. For now this comprises only erasing /// 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. void appendHighBitsCleanup(IntegerType const& _typeOnStack);