From 259d803387a9bbe301c7fc13565a1e18ef0961bb Mon Sep 17 00:00:00 2001 From: Mathias Baumann Date: Wed, 6 Feb 2019 20:42:38 +0100 Subject: [PATCH] Conditional Expression: Delay invalid type fatal error Check the whole conditional first and then output errors for both, the true and false expressions. --- libsolidity/analysis/TypeChecker.cpp | 48 ++++++++++++------- .../invalidTypes/conditional_expression.sol | 16 +++++++ 2 files changed, 47 insertions(+), 17 deletions(-) create mode 100644 test/libsolidity/syntaxTests/nameAndTypeResolution/invalidTypes/conditional_expression.sol diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index e0ac3f9d5..07c4346db 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1058,25 +1058,39 @@ bool TypeChecker::visit(Conditional const& _conditional) TypePointer trueType = type(_conditional.trueExpression())->mobileType(); TypePointer falseType = type(_conditional.falseExpression())->mobileType(); - if (!trueType) - m_errorReporter.fatalTypeError(_conditional.trueExpression().location(), "Invalid mobile type."); - if (!falseType) - m_errorReporter.fatalTypeError(_conditional.falseExpression().location(), "Invalid mobile type."); - TypePointer commonType = Type::commonType(trueType, falseType); - if (!commonType) - { - m_errorReporter.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. + TypePointer commonType; + + if (!trueType) + m_errorReporter.typeError(_conditional.trueExpression().location(), "Invalid mobile type in true expression."); + else commonType = trueType; + + if (!falseType) + m_errorReporter.typeError(_conditional.falseExpression().location(), "Invalid mobile type in false expression."); + else + commonType = falseType; + + if (!trueType && !falseType) + BOOST_THROW_EXCEPTION(FatalError()); + else if (trueType && falseType) + { + commonType = Type::commonType(trueType, falseType); + + if (!commonType) + { + m_errorReporter.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; diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/invalidTypes/conditional_expression.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/invalidTypes/conditional_expression.sol new file mode 100644 index 000000000..4cb3f6292 --- /dev/null +++ b/test/libsolidity/syntaxTests/nameAndTypeResolution/invalidTypes/conditional_expression.sol @@ -0,0 +1,16 @@ +contract C { + function o(byte) public pure {} + function f() public { + o(true ? 99**99 : 99); + o(true ? 99 : 99**99); + + o(true ? 99**99 : 99**99); + } +} +// ---- +// TypeError: (92-98): Invalid mobile type in true expression. +// TypeError: (85-103): Invalid type for argument in function call. Invalid implicit conversion from uint8 to bytes1 requested. +// TypeError: (128-134): Invalid mobile type in false expression. +// TypeError: (116-134): Invalid type for argument in function call. Invalid implicit conversion from uint8 to bytes1 requested. +// TypeError: (155-161): Invalid mobile type in true expression. +// TypeError: (164-170): Invalid mobile type in false expression.