Conditional Expression: Delay invalid type fatal error

Check the whole conditional first and then output errors for
both, the true and false expressions.
This commit is contained in:
Mathias Baumann 2019-02-06 20:42:38 +01:00
parent 08977af843
commit 259d803387
2 changed files with 47 additions and 17 deletions

View File

@ -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;

View File

@ -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.