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. diff --git a/test/libsolidity/syntaxTests/nameAndTypeResolution/586_invalid_types_for_constructor_call.sol b/test/libsolidity/syntaxTests/nameAndTypeResolution/invalidTypes/constructor_call.sol similarity index 100% rename from test/libsolidity/syntaxTests/nameAndTypeResolution/586_invalid_types_for_constructor_call.sol rename to test/libsolidity/syntaxTests/nameAndTypeResolution/invalidTypes/constructor_call.sol