diff options
author | Christian <c@ethdev.com> | 2014-12-19 01:53:43 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2014-12-19 07:12:04 +0800 |
commit | 7dc7827907087c25d89589244f7fa57f5a66e48d (patch) | |
tree | fa011514eb4cc8f56e4fec008422e19d6bb0901c /AST.cpp | |
parent | 59835e9df19332397d6e16b25bfe0dac4807996c (diff) | |
download | dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar.gz dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar.bz2 dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar.lz dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar.xz dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.tar.zst dexon-solidity-7dc7827907087c25d89589244f7fa57f5a66e48d.zip |
Possibility for binary operators to yield types different from their operands'.
Diffstat (limited to 'AST.cpp')
-rw-r--r-- | AST.cpp | 35 |
1 files changed, 15 insertions, 20 deletions
@@ -180,12 +180,18 @@ void Assignment::checkTypeRequirements() //@todo later, assignments to structs might be possible, but not to mappings if (!m_leftHandSide->getType()->isValueType() && !m_leftHandSide->isLocalLValue()) BOOST_THROW_EXCEPTION(createTypeError("Assignment to non-local non-value lvalue.")); - m_rightHandSide->expectType(*m_leftHandSide->getType()); m_type = m_leftHandSide->getType(); - if (m_assigmentOperator != Token::ASSIGN) + if (m_assigmentOperator == Token::ASSIGN) + m_rightHandSide->expectType(*m_type); + else + { // compound assignment - if (!m_type->acceptsBinaryOperator(Token::AssignmentToBinaryOp(m_assigmentOperator))) + m_rightHandSide->checkTypeRequirements(); + TypePointer resultType = Type::binaryOperatorResult(Token::AssignmentToBinaryOp(m_assigmentOperator), + m_type, m_rightHandSide->getType()); + if (!resultType || *resultType != *m_type) BOOST_THROW_EXCEPTION(createTypeError("Operator not compatible with type.")); + } } void ExpressionStatement::checkTypeRequirements() @@ -225,24 +231,13 @@ void BinaryOperation::checkTypeRequirements() { m_left->checkTypeRequirements(); m_right->checkTypeRequirements(); - if (m_right->getType()->isImplicitlyConvertibleTo(*m_left->getType())) - m_commonType = m_left->getType(); - else if (m_left->getType()->isImplicitlyConvertibleTo(*m_right->getType())) - m_commonType = m_right->getType(); - else - BOOST_THROW_EXCEPTION(createTypeError("No common type found in binary operation: " + - m_left->getType()->toString() + " vs. " + + m_commonType = Type::binaryOperatorResult(m_operator, m_left->getType(), m_right->getType()); + if (!m_commonType) + BOOST_THROW_EXCEPTION(createTypeError("Operator " + string(Token::toString(m_operator)) + + " not compatible with types " + + m_left->getType()->toString() + " and " + m_right->getType()->toString())); - if (Token::isCompareOp(m_operator)) - m_type = make_shared<BoolType>(); - else - { - m_type = m_commonType; - if (!m_commonType->acceptsBinaryOperator(m_operator)) - BOOST_THROW_EXCEPTION(createTypeError("Operator " + string(Token::toString(m_operator)) + - " not compatible with type " + - m_commonType->toString())); - } + m_type = Token::isCompareOp(m_operator) ? make_shared<BoolType>() : m_commonType; } void FunctionCall::checkTypeRequirements() |