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

View File

@ -118,17 +118,20 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope, is_force); 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 /* If the l-value doesn't elaborate, the error was
already detected and printed. We just skip it and let already detected and printed. We just skip it and let
the compiler catch more errors. */ the compiler catch more errors. */
if (tmp == 0) if (tmp == 0) continue;
continue;
assert(tmp);
/* Link the new l-value to the previous one. */ /* Link the new l-value to the previous one. */
NetAssign_*last = tmp; NetAssign_*last = tmp;
while (last->more) while (last->more)
last = last->more; last = last->more;

View File

@ -72,10 +72,16 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
} else { } else {
nets[idx] = parms_[idx]->elaborate_lnet(des, scope); 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; errors += 1;
else continue;
width += nets[idx]->vector_width(); } else width += nets[idx]->vector_width();
} }
/* If any of the sub expressions failed to elaborate, then /* 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 /* Elaborate all the operands and attach them to the concat
node. Use the elaborate_pexpr method instead of the node. Use the elaborate_pexpr method instead of the
elaborate_expr method. */ elaborate_expr method. */
bool fail = false;
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) { for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
assert(parms_[idx]); assert(parms_[idx]);
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope); NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
if (ex == 0) continue; 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]); ex->set_line(*parms_[idx]);
if (dynamic_cast<NetEParam*>(ex)) { if (dynamic_cast<NetEParam*>(ex)) {
@ -167,13 +175,18 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
<< "concatenation has indefinite width: " << "concatenation has indefinite width: "
<< *ex << endl; << *ex << endl;
des->errors += 1; des->errors += 1;
delete tmp; fail = true;
return 0; continue;
} }
tmp->set(idx, ex); tmp->set(idx, ex);
} }
if (fail) {
delete tmp;
return 0;
}
return tmp; 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 * This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU * 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) void NetScope::evaluate_parameter_real_(Design*des, param_ref_t cur)
{ {
NetExpr*expr = (*cur).second.expr; NetExpr*expr = (*cur).second.expr;
assert(expr); if (expr == NULL) return; // This is an invalid parameter so return.
NetECReal*res = 0; NetECReal*res = 0;
eval_expr(expr); eval_expr(expr);