diff options
author | Lu Guanqun <guanqun.lu@gmail.com> | 2016-01-07 17:01:46 +0800 |
---|---|---|
committer | Lu Guanqun <guanqun.lu@gmail.com> | 2016-01-23 01:14:00 +0800 |
commit | 82ee9503e9b3af35b55318f03caf3dc311a57539 (patch) | |
tree | f54d6dc2f7b1be01a05717e30da4464c1813248e /libsolidity | |
parent | c781b130ef95c1ad841ab1b80fbc95d7c068db80 (diff) | |
download | dexon-solidity-82ee9503e9b3af35b55318f03caf3dc311a57539.tar.gz dexon-solidity-82ee9503e9b3af35b55318f03caf3dc311a57539.tar.zst dexon-solidity-82ee9503e9b3af35b55318f03caf3dc311a57539.zip |
[cond-expr] change endVisit() to visit()
Diffstat (limited to 'libsolidity')
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 69 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.h | 2 |
2 files changed, 41 insertions, 30 deletions
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index b6b4ac90..f2056474 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -744,44 +744,55 @@ void TypeChecker::endVisit(ExpressionStatement const& _statement) typeError(_statement.expression().location(), "Invalid integer constant."); } -void TypeChecker::endVisit(Conditional const& _conditional) +bool TypeChecker::visit(Conditional const& _conditional) { - TypePointer const& conditionType = type(_conditional.condition()); - if (!conditionType->isImplicitlyConvertibleTo(BoolType())) - typeError( - _conditional.location(), - "Conditional expression's type " + - conditionType->toString() + - " doesn't match bool type." - ); - - TypePointer const& trueType = type(_conditional.trueExpression()); - TypePointer const& falseType = type(_conditional.falseExpression()); - // we fake it as an equal operator, but any other comparison operator can work. - TypePointer commonType = trueType->binaryOperatorResult(Token::Equal, falseType); - if (!commonType) - { - typeError( - _conditional.location(), - "True expression's type " + - trueType->toString() + - " doesn't match false expression's type " + - falseType->toString() + - "." - ); - // even we can't find a common type, we have to set a type here, - // otherwise the upper statement will not be able to check the type. - commonType = trueType; - } - _conditional.annotation().type = commonType; + expectType(_conditional.condition(), BoolType()); if (_conditional.annotation().lValueRequested) { requireLValue(_conditional.trueExpression()); requireLValue(_conditional.falseExpression()); + TypePointer const& trueType = type(_conditional.trueExpression()); + TypePointer const& falseType = type(_conditional.falseExpression()); + + // as a left value, we require exact match to prevent subtle conversion issues. + if (*trueType != *falseType) + typeError( + _conditional.location(), + "True expression's type " + + trueType->toString() + + " doesn't match false expression's type " + + falseType->toString() + + "." + ); + + _conditional.annotation().type = trueType; _conditional.annotation().isLValue = true; } + else + { + _conditional.trueExpression().accept(*this); + _conditional.falseExpression().accept(*this); + + TypePointer const& trueType = type(_conditional.trueExpression()); + TypePointer const& falseType = type(_conditional.falseExpression()); + + // we fake it as an equal operator, but any other comparison operator can work. + TypePointer commonType = trueType->binaryOperatorResult(Token::Equal, falseType); + if (!commonType) + typeError( + _conditional.location(), + "True expression's type " + + trueType->toString() + + " doesn't match false expression's type " + + falseType->toString() + + "." + ); + + _conditional.annotation().type = commonType; + } + return false; } bool TypeChecker::visit(Assignment const& _assignment) diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h index ae96229b..b884db49 100644 --- a/libsolidity/analysis/TypeChecker.h +++ b/libsolidity/analysis/TypeChecker.h @@ -90,7 +90,7 @@ private: virtual void endVisit(Return const& _return) override; virtual bool visit(VariableDeclarationStatement const& _variable) override; virtual void endVisit(ExpressionStatement const& _statement) override; - virtual void endVisit(Conditional const& _conditional) override; + virtual bool visit(Conditional const& _conditional) override; virtual bool visit(Assignment const& _assignment) override; virtual bool visit(TupleExpression const& _tuple) override; virtual void endVisit(BinaryOperation const& _operation) override; |