diff --git a/AST.h b/AST.h index f42ff47d0..f80031f42 100644 --- a/AST.h +++ b/AST.h @@ -565,12 +565,15 @@ public: Expression& getLeftExpression() const { return *m_left; } Expression& getRightExpression() const { return *m_right; } Token::Value getOperator() const { return m_operator; } + Type const& getCommonType() const { return *m_commonType; } private: ASTPointer m_left; Token::Value m_operator; ASTPointer m_right; + /// The common type that is used for the operation, not necessarily the result type (e.g. for + /// comparisons, this is always bool). std::shared_ptr m_commonType; }; diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp index d23579b11..a7d872217 100644 --- a/ExpressionCompiler.cpp +++ b/ExpressionCompiler.cpp @@ -113,7 +113,7 @@ bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation) { Expression& leftExpression = _binaryOperation.getLeftExpression(); Expression& rightExpression = _binaryOperation.getRightExpression(); - Type const& resultType = *_binaryOperation.getType(); + Type const& commonType = _binaryOperation.getCommonType(); Token::Value const op = _binaryOperation.getOperator(); if (op == Token::AND || op == Token::OR) @@ -121,23 +121,16 @@ bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation) // special case: short-circuiting appendAndOrOperatorCode(_binaryOperation); } - else if (Token::isCompareOp(op)) - { - leftExpression.accept(*this); - rightExpression.accept(*this); - - // the types to compare have to be the same, but the resulting type is always bool - if (asserts(*leftExpression.getType() == *rightExpression.getType())) - BOOST_THROW_EXCEPTION(InternalCompilerError()); - appendCompareOperatorCode(op, *leftExpression.getType()); - } else { leftExpression.accept(*this); - cleanHigherOrderBitsIfNeeded(*leftExpression.getType(), resultType); + cleanHigherOrderBitsIfNeeded(*leftExpression.getType(), commonType); rightExpression.accept(*this); - cleanHigherOrderBitsIfNeeded(*rightExpression.getType(), resultType); - appendOrdinaryBinaryOperatorCode(op, resultType); + cleanHigherOrderBitsIfNeeded(*rightExpression.getType(), commonType); + if (Token::isCompareOp(op)) + appendCompareOperatorCode(op, commonType); + else + appendOrdinaryBinaryOperatorCode(op, commonType); } // do not visit the child nodes, we already did that explicitly