diff --git a/elab_expr.cc b/elab_expr.cc index 115d17c61..a018593d4 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -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; } diff --git a/elab_lval.cc b/elab_lval.cc index 3db84356f..63f0c40c2 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -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; diff --git a/elab_net.cc b/elab_net.cc index 6ef1aaa0d..40cbc7383 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -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 diff --git a/elab_pexpr.cc b/elab_pexpr.cc index fb1454dca..b7e243341 100644 --- a/elab_pexpr.cc +++ b/elab_pexpr.cc @@ -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(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; } diff --git a/net_design.cc b/net_design.cc index 7f3ad88f1..0e09642e4 100644 --- a/net_design.cc +++ b/net_design.cc @@ -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);