From eeed05d9cdca03607b4376ba18439b1089d6c77b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 19 Feb 2022 08:21:46 +0100 Subject: [PATCH 1/2] Handle class new assignment to non-class variables Using a class new operator on a non-class variable should result in an error. At the moment when using a class new operator on a dynamic array or queue will result in an segmentation fault. This is because the implementation assumes that the left hand side is of a class type. Add a check in the class new operator implementation that the type of the left hand side is a class. Report an error if it is not. Signed-off-by: Lars-Peter Clausen --- elab_expr.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/elab_expr.cc b/elab_expr.cc index f47ec86fb..844c1e89c 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -6594,14 +6594,21 @@ NetExpr* PENewClass::elaborate_expr_constructor_(Design*des, NetScope*scope, NetExpr* PENewClass::elaborate_expr(Design*des, NetScope*scope, ivl_type_t ntype, unsigned flags) const { - NetExpr*obj = new NetENew(ntype); - obj->set_line(*this); - // Find the constructor for the class. If there is no // constructor then the result of this expression is the // allocation alone. const netclass_t*ctype = dynamic_cast (ntype); + if (!ctype) { + cerr << get_fileline() << ": error: class new not allowed here. " + << "Left-hand side is not of class type." << endl; + des->errors++; + return 0; + } + + NetExpr*obj = new NetENew(ntype); + obj->set_line(*this); + obj = elaborate_expr_constructor_(des, scope, ctype, obj, flags); return obj; } From 58ac6ed1f89695acc0c8bcef2e71b3e005c025c2 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 30 Apr 2022 20:52:15 +0200 Subject: [PATCH 2/2] Add regression tests for invalid class new Check that using a class new operator on a variable that is not of a class type results in an error. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_class_new_fail1.v | 13 +++++++++++++ ivtest/ivltests/sv_class_new_fail2.v | 13 +++++++++++++ ivtest/regress-sv.list | 2 ++ 3 files changed, 28 insertions(+) create mode 100644 ivtest/ivltests/sv_class_new_fail1.v create mode 100644 ivtest/ivltests/sv_class_new_fail2.v diff --git a/ivtest/ivltests/sv_class_new_fail1.v b/ivtest/ivltests/sv_class_new_fail1.v new file mode 100644 index 000000000..617780120 --- /dev/null +++ b/ivtest/ivltests/sv_class_new_fail1.v @@ -0,0 +1,13 @@ +// Check that using the class new operator on a non-class variable results in an +// error. + +module test; + + int i; + + initial begin + i = new; + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/sv_class_new_fail2.v b/ivtest/ivltests/sv_class_new_fail2.v new file mode 100644 index 000000000..7e4928c31 --- /dev/null +++ b/ivtest/ivltests/sv_class_new_fail2.v @@ -0,0 +1,13 @@ +// Check that using the class new operator on a dynamic array variable results +// in an error. + +module test; + + int i[]; + + initial begin + i = new; + $display("FAILED"); + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index d28634ee3..65140e653 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -499,6 +499,8 @@ sv_class_constructor_fail CE,-g2009 ivltests sv_class_empty_item normal,-g2009 ivltests sv_class_extends_scoped normal,-g2009 ivltests sv_class_localparam normal,-g2009 ivltests +sv_class_new_fail1 CE,-g2009 ivltests +sv_class_new_fail2 CE,-g2009 ivltests sv_class_new_init normal,-g2009 ivltests sv_class_in_module_decl normal,-g2009 ivltests sv_class_method_signed1 normal,-g2009 ivltests