Report an error when trying to take the concatenation of a real value.

This patch adds checks in various places to prevent the user from
taking a concatenation of a real value.
(cherry picked from commit 464310f522)
This commit is contained in:
Cary R 2009-04-02 10:03:07 -07:00 committed by Stephen Williams
parent 95848eb2f8
commit 10b8055a38
5 changed files with 45 additions and 20 deletions

View File

@ -1682,18 +1682,20 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
ex->set_line(*parms_[idx]);
if (ex->expr_type() == IVL_VT_REAL) {
cerr << ex->get_fileline() << ": error: "
<< "concatenation operand can not be real: "
<< *parms_[idx] << endl;
des->errors += 1;
continue;
}
if (! ex->has_width()) {
cerr << ex->get_fileline() << ": error: "
<< "concatenation operand has indefinite width: "
<< *ex << endl;
des->errors += 1;
}
if (ex->expr_type() == IVL_VT_REAL) {
cerr << ex->get_fileline() << ": error: "
<< "concatenation operand can not be REAL: "
<< *ex << endl;
des->errors += 1;
continue;
}
wid_sum += ex->expr_width();
@ -1707,6 +1709,7 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope,
<< "have zero width in this context." << endl;
des->errors += 1;
concat_depth -= 1;
delete tmp;
return 0;
}

View File

@ -118,17 +118,20 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force);
if (tmp->expr_type() == IVL_VT_REAL) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can not be real: "
<< *parms_[idx] << endl;
des->errors += 1;
continue;
}
/* If the l-value doesn't elaborate, the error was
already detected and printed. We just skip it and let
the compiler catch more errors. */
if (tmp == 0)
continue;
assert(tmp);
if (tmp == 0) continue;
/* Link the new l-value to the previous one. */
NetAssign_*last = tmp;
while (last->more)
last = last->more;

View File

@ -72,10 +72,16 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
} else {
nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
}
if (nets[idx] == 0)
if (nets[idx] == 0) errors += 1;
else if (nets[idx]->data_type() == IVL_VT_REAL) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can no be real: "
<< *parms_[idx] << endl;
errors += 1;
else
width += nets[idx]->vector_width();
continue;
} else width += nets[idx]->vector_width();
}
/* If any of the sub expressions failed to elaborate, then

View File

@ -150,11 +150,19 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
/* Elaborate all the operands and attach them to the concat
node. Use the elaborate_pexpr method instead of the
elaborate_expr method. */
bool fail = false;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
if (ex == 0) continue;
if (ex->expr_type() == IVL_VT_REAL) {
cerr << ex->get_fileline() << ": error: concatenation "
<< "operand can not be real: " << *ex << endl;
des->errors += 1;
fail = true;
continue;
}
ex->set_line(*parms_[idx]);
if (dynamic_cast<NetEParam*>(ex)) {
@ -167,13 +175,18 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
<< "concatenation has indefinite width: "
<< *ex << endl;
des->errors += 1;
delete tmp;
return 0;
fail = true;
continue;
}
tmp->set(idx, ex);
}
if (fail) {
delete tmp;
return 0;
}
return tmp;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2007 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -490,7 +490,7 @@ void NetScope::evaluate_parameter_logic_(Design*des, param_ref_t cur)
void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
{
NetExpr*expr = (*cur).second.expr;
assert(expr);
if (expr == NULL) return; // This is an invalid parameter so return.
NetECReal*res = 0;
eval_expr(expr);