Fix issue #265 - emit a sensible error message when an explicit cast is needed.

This commit is contained in:
Martin Whitaker 2019-10-06 17:54:44 +01:00
parent 06a60cac01
commit de54a58991
3 changed files with 36 additions and 9 deletions

View File

@ -163,15 +163,11 @@ unsigned PExpr::test_width(Design*des, NetScope*, width_mode_t&)
return 1;
}
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, ivl_type_t, unsigned) const
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*scope, ivl_type_t, unsigned flags) const
{
cerr << get_fileline() << ": internal error: I do not know how to"
<< " elaborate (ivl_type_t) this expression. " << endl;
cerr << get_fileline() << ": : Expression is: " << *this
<< endl;
cerr << get_fileline() << ": : Expression type: " << typeid(*this).name() << endl;
des->errors += 1;
return 0;
// Fall back to the old method. Currently the new method won't be used
// if the target is a vector type, so we can use an arbitrary width.
return elaborate_expr(des, scope, 1, flags);
}
@ -181,6 +177,7 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, unsigned, unsigned) const
<< " elaborate this expression. " << endl;
cerr << get_fileline() << ": : Expression is: " << *this
<< endl;
cerr << get_fileline() << ": : Expression type: " << typeid(*this).name() << endl;
des->errors += 1;
return 0;
}

View File

@ -2317,7 +2317,7 @@ NetExpr* PAssign_::elaborate_rval_(Design*des, NetScope*scope,
{
ivl_assert(*this, rval_);
NetExpr*rv = rval_->elaborate_expr(des, scope, net_type, 0);
NetExpr*rv = elab_and_eval(des, scope, rval_, net_type, is_constant_);
if (!is_constant_ || !rv) return rv;

View File

@ -1011,6 +1011,36 @@ NetExpr* elab_and_eval(Design*des, NetScope*scope, PExpr*pe,
flags |= PExpr::NEED_CONST;
NetExpr*tmp = pe->elaborate_expr(des, scope, lv_net_type, flags);
if (tmp == 0) return 0;
ivl_variable_type_t cast_type = ivl_type_base(lv_net_type);
if ((cast_type != IVL_VT_NO_TYPE) && (cast_type != tmp->expr_type())) {
// Catch some special cases.
switch (cast_type) {
case IVL_VT_DARRAY:
case IVL_VT_QUEUE:
if (dynamic_cast<PEAssignPattern*>(pe))
return tmp;
// fall through
case IVL_VT_STRING:
if (dynamic_cast<PEConcat*>(pe))
return tmp;
break;
case IVL_VT_CLASS:
if (dynamic_cast<PENull*>(pe))
return tmp;
break;
default:
break;
}
cerr << tmp->get_fileline() << ": error: "
"The expression '" << *pe << "' cannot be implicitly "
"cast to the target type." << endl;
des->errors += 1;
delete tmp;
return 0;
}
return tmp;
}