diff --git a/Changes b/Changes index 1579f5c30..58e101e16 100644 --- a/Changes +++ b/Changes @@ -22,6 +22,7 @@ Verilator 5.041 devel * Add $(LDFLAGS) and $(LIBS) to when building shared libraries (#6425) (#6426). [Ahmed El-Mahmoudy] * Add IMPLICITSTATIC also on procedure variables. * Add FUNCTIMCTL error on function invoking task or time-controlling statements (#6385). +* Add error on `virtual new` (#6486). [Alex Solomatnikov] * Deprecate sensitivity list on public_flat_rw attributes (#6443). [Geza Lore] * Deprecate clocker attribute and --clk option (#6463). [Geza Lore] * Support modports referencing clocking blocks (#4555) (#6436). [Ryszard Rozak, Antmicro Ltd.] diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 4cc8278ae..aee13075e 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -6254,6 +6254,12 @@ class WidthVisitor final : public VNVisitor { nodep->v3error("The 'constraint_mode' method is built-in and cannot be overridden" " (IEEE 1800-2023 18.9)"); } + if (nodep->classMethod() && nodep->name() == "new") { + if (nodep->isVirtual()) + nodep->v3error("class 'new()' cannot be virual (IEEE 1800-2023 18.3)"); + if (nodep->isStatic()) + nodep->v3error("class 'new()' cannot be static (IEEE 1800-2023 18.3)"); + } // Function hasn't been widthed, so make it so. // Would use user1 etc, but V3Width called from too many places to spend a user nodep->doingWidth(true); diff --git a/test_regress/t/t_class_new_bad.out b/test_regress/t/t_class_new_bad.out index f0f0b6672..0b66b6eb5 100644 --- a/test_regress/t/t_class_new_bad.out +++ b/test_regress/t/t_class_new_bad.out @@ -1,22 +1,34 @@ -%Error: t/t_class_new_bad.v:31:16: Too many arguments in function call to FUNC 'new' +%Error: t/t_class_new_bad.v:27:19: class 'new()' cannot be static (IEEE 1800-2023 18.3) : ... note: In instance 't' - 31 | c1 = new(3); - | ^ + 27 | static function new(); + | ^~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_class_new_bad.v:32:16: Too many arguments in function call to FUNC 'new' +%Error: t/t_class_new_bad.v:32:20: class 'new()' cannot be virual (IEEE 1800-2023 18.3) : ... note: In instance 't' - 32 | c2 = new(3); + 32 | virtual function new(); + | ^~~ +%Error: t/t_class_new_bad.v:39:19: class 'new()' cannot be virual (IEEE 1800-2023 18.3) + : ... note: In instance 't' + 39 | function ClsNew3::new(); + | ^~~ +%Error: t/t_class_new_bad.v:47:16: Too many arguments in function call to FUNC 'new' + : ... note: In instance 't' + 47 | c1 = new(3); | ^ -%Error: t/t_class_new_bad.v:33:12: Missing argument on non-defaulted argument 'i' in function call to FUNC 'new' +%Error: t/t_class_new_bad.v:48:16: Too many arguments in function call to FUNC 'new' : ... note: In instance 't' - 33 | c3 = new(); - | ^~~ -%Error: t/t_class_new_bad.v:34:12: dynamic new() not expected in this context (data type must be dynamic array) + 48 | c2 = new(3); + | ^ +%Error: t/t_class_new_bad.v:49:12: Missing argument on non-defaulted argument 'i' in function call to FUNC 'new' : ... note: In instance 't' - 34 | c1 = new[2]; + 49 | c3 = new(); | ^~~ -%Error: Internal Error: t/t_class_new_bad.v:34:12: ../V3Width.cpp:#: Node has no type +%Error: t/t_class_new_bad.v:50:12: dynamic new() not expected in this context (data type must be dynamic array) + : ... note: In instance 't' + 50 | c1 = new[2]; + | ^~~ +%Error: Internal Error: t/t_class_new_bad.v:50:12: ../V3Width.cpp:#: Node has no type : ... note: In instance 't' - 34 | c1 = new[2]; + 50 | c1 = new[2]; | ^~~ ... This fatal error may be caused by the earlier error(s); resolve those first. diff --git a/test_regress/t/t_class_new_bad.v b/test_regress/t/t_class_new_bad.v index 234cdba25..245290bf8 100644 --- a/test_regress/t/t_class_new_bad.v +++ b/test_regress/t/t_class_new_bad.v @@ -23,6 +23,22 @@ class ClsArg; endfunction endclass +class ClsNew1; + static function new(); // <--- Error: new can't be static + endfunction +endclass + +class ClsNew2; + virtual function new(); // <--- Error: new can't be virtual + endfunction +endclass + +class ClsNew3; + extern virtual function new(); // <--- Error: new can't be virtual +endclass +function ClsNew3::new(); +endfunction + module t; initial begin ClsNoArg c1;