Merge pull request #1404 from sifferman/param-string-compare
Fix assert on constant == with unequal-length string operands
This commit is contained in:
commit
50b477bc1f
11
elab_expr.cc
11
elab_expr.cc
|
|
@ -916,6 +916,17 @@ NetExpr* PEBComp::elaborate_expr(Design*des, NetScope*scope,
|
||||||
eval_expr(lp, l_width_);
|
eval_expr(lp, l_width_);
|
||||||
eval_expr(rp, r_width_);
|
eval_expr(rp, r_width_);
|
||||||
|
|
||||||
|
// test_width() does not equalize operand widths for string
|
||||||
|
// operands, but constant evaluation expects equal widths.
|
||||||
|
if (left_->expr_type() == IVL_VT_STRING ||
|
||||||
|
right_->expr_type() == IVL_VT_STRING) {
|
||||||
|
if (dynamic_cast<NetEConst*>(lp) && dynamic_cast<NetEConst*>(rp)) {
|
||||||
|
unsigned use_wid = max(lp->expr_width(), rp->expr_width());
|
||||||
|
lp = pad_to_width(lp, use_wid, false, *this);
|
||||||
|
rp = pad_to_width(rp, use_wid, false, *this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle some operand-specific special cases...
|
// Handle some operand-specific special cases...
|
||||||
switch (op_) {
|
switch (op_) {
|
||||||
case 'E': /* === */
|
case 'E': /* === */
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
// Regression test: comparing a `string` parameter to a string constant of
|
||||||
|
// a different length must constant-fold cleanly instead of tripping the
|
||||||
|
// "lv.len() == rv.len()" assertion in the NetEBComp evaluation functions.
|
||||||
|
// Covers ==, !=, ===, !==, ==? and !=? with the string operand on either
|
||||||
|
// side and both shorter and longer than the other operand.
|
||||||
|
|
||||||
|
module main #(parameter string Target = "A",
|
||||||
|
parameter string Long = "ABC");
|
||||||
|
|
||||||
|
integer errors = 0;
|
||||||
|
|
||||||
|
// Equality / inequality, parameter shorter than the literal.
|
||||||
|
if (Target == "AA") initial begin errors += 1; $display("FAILED: Target == \"AA\""); end
|
||||||
|
if (Target != "A") initial begin errors += 1; $display("FAILED: Target != \"A\""); end
|
||||||
|
|
||||||
|
// Literal on the left.
|
||||||
|
if ("AA" == Target) initial begin errors += 1; $display("FAILED: \"AA\" == Target"); end
|
||||||
|
|
||||||
|
// Parameter longer than the literal.
|
||||||
|
if (Long == "AB") initial begin errors += 1; $display("FAILED: Long == \"AB\""); end
|
||||||
|
if (Long != "ABC") initial begin errors += 1; $display("FAILED: Long != \"ABC\""); end
|
||||||
|
|
||||||
|
// Two string parameters of different lengths.
|
||||||
|
if (Target == Long) initial begin errors += 1; $display("FAILED: Target == Long"); end
|
||||||
|
|
||||||
|
// Case equality.
|
||||||
|
if (Target === "AA") initial begin errors += 1; $display("FAILED: Target === \"AA\""); end
|
||||||
|
if (Target !== "A") initial begin errors += 1; $display("FAILED: Target !== \"A\""); end
|
||||||
|
|
||||||
|
// Wildcard equality.
|
||||||
|
if (Target ==? "AA") initial begin errors += 1; $display("FAILED: Target ==? \"AA\""); end
|
||||||
|
if (Target !=? "A") initial begin errors += 1; $display("FAILED: Target !=? \"A\""); end
|
||||||
|
|
||||||
|
initial #1 if (errors == 0) $display("PASSED");
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -416,6 +416,7 @@ net_string_fail CE,-g2005-sv ivltests
|
||||||
package_vec_part_select normal,-g2005-sv ivltests
|
package_vec_part_select normal,-g2005-sv ivltests
|
||||||
packeda normal,-g2009 ivltests
|
packeda normal,-g2009 ivltests
|
||||||
packeda2 normal,-g2009 ivltests
|
packeda2 normal,-g2009 ivltests
|
||||||
|
param_string_compare normal,-g2009 ivltests
|
||||||
parameter_in_generate2 CE,-g2005-sv ivltests
|
parameter_in_generate2 CE,-g2005-sv ivltests
|
||||||
parameter_no_default normal,-g2005-sv ivltests
|
parameter_no_default normal,-g2005-sv ivltests
|
||||||
parameter_no_default_fail1 CE ivltests
|
parameter_no_default_fail1 CE ivltests
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue