Reject unpacked l-value concatenation operands

L-value concatenation operands must be packed values. Using an unpacked
array, string, class object or other non-packed value as an operand can
reach later assignment code with an invalid l-value representation.

Check the operand type after l-value elaboration and report an
elaboration error instead.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2026-05-10 21:21:39 -07:00
parent 73ae5bd1db
commit 208078838e
2 changed files with 20 additions and 12 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2026 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -133,11 +133,13 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
the compiler catch more errors. */
if (tmp == 0) continue;
if (tmp->expr_type() == IVL_VT_REAL) {
ivl_type_t tmp_type = tmp->net_type();
if (tmp_type && !tmp_type->packed()) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand can not be real: "
<< "concatenation operand must be packed: "
<< *parms_[idx] << endl;
des->errors += 1;
delete tmp;
continue;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2025 Stephen Williams (steve@icarus.com)
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
@ -83,16 +83,22 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
}
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;
continue;
} else {
width += nets[idx]->vector_width();
}
ivl_type_t tmp_type = nets[idx]->array_type();
if (!tmp_type)
tmp_type = nets[idx]->net_type();
if (tmp_type && !tmp_type->packed()) {
cerr << parms_[idx]->get_fileline() << ": error: "
<< "concatenation operand must be packed: "
<< *parms_[idx] << endl;
errors += 1;
continue;
}
width += nets[idx]->vector_width();
}
}
if (errors) {