From 6bb16d6c52f88fa3d93d26d77fade2bedfc07d07 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Sat, 17 May 2025 22:21:14 -0400 Subject: [PATCH] Disable symbol from parser: Support redeclaring type as non-type; major parsing change (#2412). --- docs/gen/ex_PKGNODECL_faulty.rst | 11 ---- docs/gen/ex_PKGNODECL_msg.rst | 4 -- docs/guide/warnings.rst | 22 ++----- src/V3Ast.h | 5 ++ src/V3AstNodeExpr.h | 8 +-- src/V3LinkDot.cpp | 56 ++++++++++++++--- src/V3ParseGrammar.cpp | 1 - src/V3ParseImp.cpp | 61 +++++++++++-------- src/V3ParseImp.h | 1 + src/astgen | 27 +++++++- src/verilog.y | 45 +++++++------- test_regress/t/t_covergroup_unsup.out | 9 +-- test_regress/t/t_dist_warn_coverage.py | 3 + test_regress/t/t_inst_paren_bad.out | 9 ++- test_regress/t/t_interface_missing_bad.out | 8 +-- .../t/t_interface_paren_missing_bad.out | 4 +- test_regress/t/t_interface_top_bad.out | 1 + test_regress/t/t_interface_typedef.out | 4 -- test_regress/t/t_interface_typo_bad.out | 1 + test_regress/t/t_lint_implicit_type_bad.out | 8 ++- test_regress/t/t_lint_implicit_type_bad.py | 2 +- test_regress/t/t_lint_import_name2_bad.out | 4 -- test_regress/t/t_lint_pkg_colon_bad.out | 10 +-- test_regress/t/t_lint_pkgnodecl_bad.out | 5 -- test_regress/t/t_lint_pkgnodecl_bad.py | 29 --------- test_regress/t/t_lint_pkgnodecl_bad.v | 12 ---- test_regress/t/t_no_std_bad.out | 4 -- test_regress/t/t_package_alone_bad.out | 6 +- test_regress/t/t_parse_sync_bad2.out | 26 ++++++-- test_regress/t/t_pp_circ_subst_bad.out | 2 +- test_regress/t/t_pp_circ_subst_bad2.out | 2 +- test_regress/t/t_preproc_inc_bad.out | 2 +- test_regress/t/t_type_non_type.py | 18 ++++++ test_regress/t/t_type_non_type.v | 49 +++++++++++++++ test_regress/t/t_vams_kwd_bad.out | 2 +- 35 files changed, 263 insertions(+), 198 deletions(-) delete mode 100644 docs/gen/ex_PKGNODECL_faulty.rst delete mode 100644 docs/gen/ex_PKGNODECL_msg.rst delete mode 100644 test_regress/t/t_lint_pkgnodecl_bad.out delete mode 100755 test_regress/t/t_lint_pkgnodecl_bad.py delete mode 100644 test_regress/t/t_lint_pkgnodecl_bad.v create mode 100755 test_regress/t/t_type_non_type.py create mode 100644 test_regress/t/t_type_non_type.v diff --git a/docs/gen/ex_PKGNODECL_faulty.rst b/docs/gen/ex_PKGNODECL_faulty.rst deleted file mode 100644 index 1f0b81529..000000000 --- a/docs/gen/ex_PKGNODECL_faulty.rst +++ /dev/null @@ -1,11 +0,0 @@ -.. comment: generated by t_lint_pkgnodecl_bad -.. code-block:: sv - :linenos: - :emphasize-lines: 2 - - module t; - initial Pkg::hello(); //<--- Warning - endmodule - package Pkg; - function void hello(); endfunction - endpackage diff --git a/docs/gen/ex_PKGNODECL_msg.rst b/docs/gen/ex_PKGNODECL_msg.rst deleted file mode 100644 index 7c772b7c4..000000000 --- a/docs/gen/ex_PKGNODECL_msg.rst +++ /dev/null @@ -1,4 +0,0 @@ -.. comment: generated by t_lint_pkgnodecl_bad -.. code-block:: - - %Error-PKGNODECL: example.v:1:12 Package/class 'Pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3) diff --git a/docs/guide/warnings.rst b/docs/guide/warnings.rst index 9678be1a9..67aa1f92c 100644 --- a/docs/guide/warnings.rst +++ b/docs/guide/warnings.rst @@ -1401,23 +1401,11 @@ List Of Warnings .. option:: PKGNODECL - An error that a package/class appears to have been referenced that has - not yet been declared. According to IEEE 1800-2023 26.3, all packages - must be declared before being used. - - Faulty example: - - .. include:: ../../docs/gen/ex_PKGNODECL_faulty.rst - - Results in: - - .. include:: ../../docs/gen/ex_PKGNODECL_msg.rst - - Often the package is declared in its own header file. In this case add - an include of that package header file to the referencing file. (And - make sure you have header guards in the package's header file to prevent - multiple declarations of the package.) - + Never issued since version 5.038. Historically an error that a + package/class appears to have been referenced that has not yet been + declared. According to IEEE 1800-2023 26.3, all packages must be + declared before being used. However, several standard libraries + including UVM violate this, and other tools do not warn. .. option:: PORTSHORT diff --git a/src/V3Ast.h b/src/V3Ast.h index fee64ac13..2a4f84617 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -2128,6 +2128,9 @@ protected: // Use instead isSame(), this is for each Ast* class, and assumes node is of same type virtual bool sameNode(const AstNode*) const { return true; } + // Generated by 'astgen'. If do an oldp->replaceNode(newp), would cause a broken() + virtual bool wouldBreakGen(const AstNode* const oldp, + const AstNode* const newp) const = 0; // Generated by 'astgen' public: // ACCESSORS @@ -2527,6 +2530,8 @@ public: virtual const char* broken() const { return nullptr; } // Generated by 'astgen'. Calls 'broken()', which can be used to add extra checks virtual const char* brokenGen() const = 0; // Generated by 'astgen' + // If do a this->replaceNode(newp), would cause a broken() + bool wouldBreak(const AstNode* const newp) const { return backp()->wouldBreakGen(this, newp); } // INVOKERS virtual void accept(VNVisitorConst& v) = 0; diff --git a/src/V3AstNodeExpr.h b/src/V3AstNodeExpr.h index 8366f6f8d..ce027827f 100644 --- a/src/V3AstNodeExpr.h +++ b/src/V3AstNodeExpr.h @@ -742,10 +742,10 @@ public: class AstCellRef final : public AstNodeExpr { // As-of-yet unlinkable reference into a cell // @astgen op1 := cellp : AstNode - // @astgen op2 := exprp : AstNodeExpr + // @astgen op2 := exprp : AstNode string m_name; // Cell name public: - AstCellRef(FileLine* fl, const string& name, AstNode* cellp, AstNodeExpr* exprp) + AstCellRef(FileLine* fl, const string& name, AstNode* cellp, AstNode* exprp) : ASTGEN_SUPER_CellRef(fl) , m_name{name} { this->cellp(cellp); @@ -1206,8 +1206,8 @@ public: class AstDot final : public AstNodeExpr { // A dot separating paths in an AstVarXRef, AstFuncRef or AstTaskRef // These are eliminated in the link stage - // @astgen op1 := lhsp : AstNodeExpr - // @astgen op2 := rhsp : AstNodeExpr + // @astgen op1 := lhsp : AstNode + // @astgen op2 := rhsp : AstNode // // We don't have a list of elements as it's probably legal to do '(foo.bar).(baz.bap)' const bool m_colon; // Is a "::" instead of a "." (lhs must be package/class) diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index b5090ce22..45885310b 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -529,7 +529,10 @@ public: "Unsupported: Interfaced port on top level module"); } ifacerefp->v3error("Parent instance's interface is not found: " - << AstNode::prettyNameQ(ifacerefp->ifaceName())); + << AstNode::prettyNameQ(ifacerefp->ifaceName()) << '\n' + << ifacerefp->warnMore() + << "... Perhaps intended an interface instantiation but " + "are missing parenthesis (IEEE 1800-2023 25.3)?"); } else { ifacerefp->v3warn( E_UNSUPPORTED, @@ -1550,11 +1553,11 @@ class LinkDotFindVisitor final : public VNVisitor { if (tdefp && tdefp->name() == nodep->name() && m_statep->forPrimary()) { UINFO(8, "Replacing type of" << nodep << endl << " with " << tdefp << endl); - AstNodeDType* const newType = tdefp->childDTypep(); - AstNodeDType* const oldType = nodep->childDTypep(); + AstNodeDType* const newDtp = tdefp->childDTypep(); + AstNodeDType* const oldDtp = nodep->childDTypep(); - oldType->replaceWith(newType->cloneTree(false)); - oldType->deleteTree(); + oldDtp->replaceWith(newDtp->cloneTree(false)); + oldDtp->deleteTree(); } } } @@ -2477,7 +2480,7 @@ class LinkDotResolveVisitor final : public VNVisitor { } void checkNoDot(AstNode* nodep) { if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) { - // UINFO(9, indent() << "ds=" << m_ds.ascii() << endl); + UINFO(9, indent() << "ds=" << m_ds.ascii() << endl); nodep->v3error("Syntax error: Not expecting " << nodep->type() << " under a " << nodep->backp()->type() << " in dotted expression\n" @@ -2608,6 +2611,15 @@ class LinkDotResolveVisitor final : public VNVisitor { symIterateNull(nodep, m_statep->getNodeSym(nodep)); } + void replaceWithCheckBreak(AstNode* oldp, AstNodeDType* newp) { + // Flag now to avoid V3Broken throwing an internal error + if (oldp->wouldBreak(newp)) { + newp->v3error( + "Data type used where a non-data type is expected: " << newp->prettyNameQ()); + } + oldp->replaceWith(newp); + } + // Marks the current module to be revisited after the initial AST iteration void revisitLater(AstNode* deferredNodep) { // Need to revisit entire module to build up all the necessary context @@ -2951,7 +2963,7 @@ class LinkDotResolveVisitor final : public VNVisitor { nodep->replaceWith(newp); VL_DO_DANGLING(pushDeletep(nodep), nodep); } else { // Dot midpoint - AstNodeExpr* newp = nodep->rhsp()->unlinkFrBack(); + AstNode* newp = nodep->rhsp()->unlinkFrBack(); if (m_ds.m_unresolvedCell) { AstCellRef* const crp = new AstCellRef{ nodep->fileline(), nodep->name(), nodep->lhsp()->unlinkFrBack(), newp}; @@ -3059,7 +3071,7 @@ class LinkDotResolveVisitor final : public VNVisitor { return; } else if (m_ds.m_dotPos == DP_MEMBER) { // Found a Var, everything following is membership. {scope}.{var}.HERE {member} - AstNodeExpr* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); + AstNodeExpr* const varEtcp = VN_AS(m_ds.m_dotp->lhsp()->unlinkFrBack(), NodeExpr); AstNodeExpr* const newp = new AstMemberSel{nodep->fileline(), varEtcp, VFlagChildDType{}, nodep->name()}; if (m_ds.m_dotErr) { @@ -3348,6 +3360,14 @@ class LinkDotResolveVisitor final : public VNVisitor { ok = true; m_ds.m_dotPos = DP_MEMBER; m_ds.m_dotText = ""; + } else if (AstClass* const defp = VN_CAST(foundp->nodep(), Class)) { + if (allowVar) { + AstRefDType* const newp = new AstRefDType{nodep->fileline(), nodep->name()}; + replaceWithCheckBreak(nodep, newp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + ok = true; + m_ds.m_dotText = ""; + } } else if (AstEnumItem* const valuep = VN_CAST(foundp->nodep(), EnumItem)) { if (allowVar) { AstNode* const newp @@ -3386,6 +3406,22 @@ class LinkDotResolveVisitor final : public VNVisitor { VL_DO_DANGLING(pushDeletep(nodep), nodep); } } + } else if (AstTypedef* const defp = VN_CAST(foundp->nodep(), Typedef)) { + ok = m_ds.m_dotPos == DP_NONE || m_ds.m_dotPos == DP_SCOPE; + if (ok) { + AstRefDType* const refp = new AstRefDType{nodep->fileline(), nodep->name()}; + refp->typedefp(defp); + replaceWithCheckBreak(nodep, refp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + } + } else if (AstParamTypeDType* const defp = VN_CAST(foundp->nodep(), ParamTypeDType)) { + ok = (m_ds.m_dotPos == DP_NONE || m_ds.m_dotPos == DP_SCOPE); + if (ok) { + AstRefDType* const refp = new AstRefDType{nodep->fileline(), nodep->name()}; + refp->refDTypep(defp); + replaceWithCheckBreak(nodep, refp); + VL_DO_DANGLING(pushDeletep(nodep), nodep); + } } if (!ok) { if (m_insideClassExtParam) { @@ -3795,7 +3831,7 @@ class LinkDotResolveVisitor final : public VNVisitor { } else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) { // Found a Var, everything following is method call. // {scope}.{var}.HERE {method} ( ARGS ) - AstNodeExpr* const varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack(); + AstNodeExpr* const varEtcp = VN_AS(m_ds.m_dotp->lhsp()->unlinkFrBack(), NodeExpr); AstNodeExpr* argsp = nullptr; if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext(); AstNode* const newp = new AstMethodCall{nodep->fileline(), varEtcp, VFlagChildDType{}, @@ -4373,7 +4409,7 @@ class LinkDotResolveVisitor final : public VNVisitor { } VL_DO_DANGLING(cpackagep->unlinkFrBack()->deleteTree(), cpackagep); } - if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) { + if (m_ds.m_dotp && (m_ds.m_dotPos == DP_PACKAGE || m_ds.m_dotPos == DP_SCOPE)) { UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(), "Bad package link"); auto* const cpackagerefp = VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef); diff --git a/src/V3ParseGrammar.cpp b/src/V3ParseGrammar.cpp index 0d0cbd5c6..bfa59ed7b 100644 --- a/src/V3ParseGrammar.cpp +++ b/src/V3ParseGrammar.cpp @@ -196,7 +196,6 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, const string& name, if (GRAMMARP->m_varIO == VDirection::NONE // In non-ANSI port list && GRAMMARP->m_varDecl == VVarType::PORT) { // Just a port list with variable name (not v2k format); AstPort already created - if (dtypep) fileline->v3warn(E_UNSUPPORTED, "Unsupported: Ranges ignored in port-lists"); if (arrayp) VL_DO_DANGLING(arrayp->deleteTree(), arrayp); if (attrsp) { // TODO: Merge attributes across list? Or warn attribute is ignored diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index b33972145..244636b6f 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -429,6 +429,35 @@ size_t V3ParseImp::tokenPipeScanIdInst(size_t depthIn) { return depth; } +size_t V3ParseImp::tokenPipeScanIdType(size_t depthIn) { + // Search around IEEE data type identifier + // Return location of following token, or input if not found + // tokenPipeScanIdCell has precedence over this search + // yaID/*type_identifier*/ [ '#' '('...')' ] [{ '['...']' }] yaID/*identifier*/ + // assignment_pattern_expression: + // yaID/*type_identifier*/ [ '#' '('...')' ] [{ '['...']' }] yP_TICKBRA + // class_type parameter_value_assignment // often followed by ) as in e.g. ClsA#(ClsB#(...)) + // yaID/*type_identifier*/ '#' '('...')' [^ '::'] + // and caller must check does NOT match tokenPipeScanIdCell + size_t depth = depthIn; + // UINFO(9, "tokenPipeScanType START d=" + // << depth << " " << V3ParseImp::tokenName(tokenPeekp(depth)->token) << endl); + if (tokenPeekp(depth)->token == '#' && tokenPeekp(depth + 1)->token == '(') { + depth = tokenPipeScanParam(depth, false); + // Not :: as then it's a yaID__CC, we'll parse that in tokenPipeScanId + if (tokenPeekp(depth)->token != yP_COLONCOLON) return depth; + } + + depth = tokenPipeScanBracket(depth); // [ '['..']' ]* + + if (tokenPeekp(depth)->token != yaID__LEX && tokenPeekp(depth)->token != yP_TICKBRA) + return depthIn; + ++depth; + // UINFO(9, "tokenPipeScanType MATCH\n"); + + return depth; +} + size_t V3ParseImp::tokenPipeScanBracket(size_t inDepth) { // Return location of following token, or input if not found // [ '['...']' ]* @@ -531,6 +560,7 @@ int V3ParseImp::tokenPipelineId(int token) { if (m_tokenLastBison.token != '@' && m_tokenLastBison.token != '#' && m_tokenLastBison.token != '.') { if (const size_t depth = tokenPipeScanIdInst(0)) return yaID__aINST; + if (const size_t depth = tokenPipeScanIdType(0)) return yaID__aTYPE; } if (nexttok == '#') { // e.g. class_type parameter_value_assignment '::' const size_t depth = tokenPipeScanParam(0, false); @@ -683,6 +713,8 @@ void V3ParseImp::tokenPipelineSym() { foundp = V3ParseImp::parsep()->symp()->symCurrentp()->findIdFallback(*(yylval.strp)); } if (!foundp && !m_afterColonColon) { // Check if the symbol can be found in std + // The following keywords from this file are hardcoded for detection in the parser: + // "mailbox", "process", "randomize", "semaphore", "std" AstPackage* const stdpkgp = v3Global.rootp()->stdPackagep(); if (stdpkgp) { VSymEnt* const stdsymp = stdpkgp->user4u().toSymEnt(); @@ -694,36 +726,11 @@ void V3ParseImp::tokenPipelineSym() { yylval.scp = scp; UINFO(7, " tokenPipelineSym: Found " << scp << endl); if (token == yaID__LEX) { // i.e. not yaID__CC - if (VN_IS(scp, Typedef)) { - token = yaID__aTYPE; - } else if (VN_IS(scp, TypedefFwd)) { - token = yaID__aTYPE; - } else if (VN_IS(scp, Class)) { - token = yaID__aTYPE; - } else if (VN_IS(scp, Package)) { - token = yaID__ETC; - } else { - token = yaID__ETC; - } + token = yaID__ETC; } } else { // Not found yylval.scp = nullptr; - if (token == yaID__CC) { - if (!m_afterColonColon && !v3Global.opt.bboxUnsup()) { - // IEEE does require this, but we may relax this as UVM breaks it, so allow - // bbox for today - // We'll get a parser error eventually but might not be obvious - // is missing package, and this confuses people - static int warned = false; - if (!warned++) { - yylval.fl->v3warn(PKGNODECL, "Package/class '" + *yylval.strp - + "' not found, and needs to be " - "predeclared (IEEE 1800-2023 26.3)"); - } - } - } else if (token == yaID__LEX) { - token = yaID__ETC; - } + if (token == yaID__LEX) token = yaID__ETC; } } m_afterColonColon = token == yP_COLONCOLON; diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 22778a657..e2fcf0990 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -316,6 +316,7 @@ private: int tokenPipelineId(int token) VL_MT_DISABLED; void tokenPipelineSym() VL_MT_DISABLED; size_t tokenPipeScanIdInst(size_t depth) VL_MT_DISABLED; + size_t tokenPipeScanIdType(size_t depth) VL_MT_DISABLED; size_t tokenPipeScanBracket(size_t depth) VL_MT_DISABLED; size_t tokenPipeScanParam(size_t depth, bool forInst) VL_MT_DISABLED; size_t tokenPipeScanTypeEq(size_t depth) VL_MT_DISABLED; diff --git a/src/astgen b/src/astgen index d5cb5edcb..c7f98404f 100755 --- a/src/astgen +++ b/src/astgen @@ -968,7 +968,31 @@ def write_ast_impl(filename): emitBlock("));\n") # Node's broken rules can be specialized by declaring broken() emitBlock(" return Ast{t}::broken();\n", t=node.name) - emitBlock("}}\n", t=node.name) + emitBlock("}}\n") + + emitBlock( + "bool Ast{t}::wouldBreakGen(const AstNode* const oldp, const AstNode* const newp) const {{\n", + t=node.name) + for i in range(1, 5): + op = node.getOp(i) + if op is None: + continue + name, _, _, legals = op + if legals != '': + # 'this' is a parent, where oldp replacing newp as op1p, must follow op1p's rules + # Could also be on a list, we don't check for speed reasons and as V3Broken doesn't + emitBlock(" if (oldp == op{i}p() && !(", i=i) + eor = "" + for legal in legals.split('|'): + emitBlock("{eor}privateTypeTest(newp)", + eor=eor, + name=name, + legal=legal) + eor = " || " + emitBlock(")) return true;\n") + # Node's broken rules can be specialized by declaring broken() + emitBlock(" return false;\n") + emitBlock("}}\n") emitBlock("void Ast{t}::cloneRelinkGen() {{\n", t=node.name) if node.superClass.name != 'Node': @@ -1042,6 +1066,7 @@ def write_ast_macros(filename): Ast{t}* clonep() const {{ return static_cast(AstNode::clonep()); }} Ast{t}* addNext(Ast{t}* nodep) {{ return static_cast(AstNode::addNext(this, nodep)); }} const char* brokenGen() const override; + bool wouldBreakGen(const AstNode* const oldp, const AstNode* const newp) const override; void cloneRelinkGen() override; void dumpTreeJsonOpGen(std::ostream& str, const string& indent) const override; void dumpJsonGen(std::ostream& str) const; diff --git a/src/verilog.y b/src/verilog.y index 6af7811b6..91a19e004 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1552,15 +1552,11 @@ port: // ==IEEE: port // // IEEE: interface_port_header port_identifier { unpacked_dimension } // // Expanded interface_port_header // // We use instantCb here because the non-port form looks just like a module instantiation - portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE - { // VAR for now, but V3LinkCells may call setIfcaeRef on it later - $$ = $3; VARDECL(VAR); VARIO(NONE); - // Although know it's an interface, use AstRefDType for forward compatibility - // with future parser. V3LinkCells will convert to AstIfaceRefDType. - AstNodeDType* const dtp = new AstRefDType{$2, *$2}; - VARDTYPE(dtp); - addNextNull($$, VARDONEP($$, $4, $5)); } - | portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE + // + // // Looks identical to variable_declaration, so V3LinkDot must resolve when ID known + // // NO: portDirNetE id/*interface*/ portSig variable_dimensionListE sigAttrListE + // + portDirNetE id/*interface*/ '.' idAny/*modport*/ portSig variable_dimensionListE sigAttrListE { // VAR for now, but V3LinkCells may call setIfcaeRef on it later $$ = $5; VARDECL(VAR); VARIO(NONE); AstNodeDType* const dtp = new AstIfaceRefDType{$2, $4, "", *$2, *$4}; @@ -1615,17 +1611,20 @@ port: // ==IEEE: port // // IEEE: portDirNetE data_type '.' portSig -> handled with AstDot in expr. // | portDirNetE data_type portSig variable_dimensionListE sigAttrListE - { $$ = $3; VARDTYPE($2); VARIOANSI(); addNextNull($$, VARDONEP($$, $4, $5)); } + { $$ = $3; VARDTYPE($2); VARIOANSI(); + addNextNull($$, VARDONEP($$, $4, $5)); } | portDirNetE data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$ = $3; VARDTYPE($2); VARIOANSI(); if (AstVar* vp = VARDONEP($$, $4, $5)) { addNextNull($$, vp); vp->valuep($7); } } | portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE - { $$ = $4; VARDTYPE($3); VARIOANSI(); addNextNull($$, VARDONEP($$, $5, $6)); } + { $$ = $4; VARDTYPE($3); VARIOANSI(); + addNextNull($$, VARDONEP($$, $5, $6)); } | portDirNetE yVAR data_type portSig variable_dimensionListE sigAttrListE '=' constExpr { $$ = $4; VARDTYPE($3); VARIOANSI(); if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } } | portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE - { $$ = $4; VARDTYPE($3); VARIOANSI(); addNextNull($$, VARDONEP($$, $5, $6)); } + { $$ = $4; VARDTYPE($3); VARIOANSI(); + addNextNull($$, VARDONEP($$, $5, $6)); } | portDirNetE yVAR implicit_typeE portSig variable_dimensionListE sigAttrListE '=' constExpr { $$ = $4; VARDTYPE($3); VARIOANSI(); if (AstVar* vp = VARDONEP($$, $5, $6)) { addNextNull($$, vp); vp->valuep($8); } } @@ -2105,13 +2104,10 @@ port_declaration: // ==IEEE: port_declaration // // // IEEE: interface_port_declaration // // IEEE: interface_identifier list_of_interface_identifiers - | id/*interface*/ - /*mid*/ { VARRESET_NONLIST(VVarType::IFACEREF); - AstIfaceRefDType* const dtp = new AstIfaceRefDType{$1, "", *$1}; - dtp->isPortDecl(true); - VARDTYPE(dtp); } - /*cont*/ mpInstnameList - { $$ = VARDONEP($3, nullptr, nullptr); } + // + // // Identical to variable_declaration, resolve in V3LinkDot when id known + // // NO: id/*interface*/ mpInstnameList + // // // IEEE: interface_port_declaration // // IEEE: interface_identifier '.' modport_identifier list_of_interface_identifiers | id/*interface*/ '.' idAny/*modport*/ @@ -4585,9 +4581,10 @@ exprOrDataType: // expr | data_type: combined to prevent conflic // // data_type includes id that overlaps expr, so special flavor // // data_type expanded: | data_typeNoRef { $$ = $1; } - | packageClassScopeE idType packed_dimensionListE - { AstRefDType* const refp = new AstRefDType{$2, *$2, $1, nullptr}; - $$ = GRAMMARP->createArray(refp, $3, true); } + // + // // Conflicts with non-type id, resolved in V3LinkDot + // // NO: packageClassScopeE idType packed_dimensionListE + // | packageClassScopeE idType parameter_value_assignmentClass packed_dimensionListE { AstRefDType* const refp = new AstRefDType{$2, *$2, $1, $3}; $$ = GRAMMARP->createArray(refp, $4, true); } @@ -5153,8 +5150,8 @@ expr: // IEEE: part of expression/constant_expression/ { $$ = new AstCast{$2, $4, VFlagChildDType{}, $1}; } // // expanded from simple_type ps_type_identifier (part of simple_type) // // expanded from simple_type ps_parameter_identifier (part of simple_type) - | packageClassScopeE idType yP_TICK '(' expr ')' - { $$ = new AstCastParse{$3, $5, new AstRefDType{$2, *$2, $1, nullptr}}; } + // // Causes conflict, so handled post-parse + // // NO: packageClassScopeE idType yP_TICK '(' expr ')' // | yTYPE__ETC '(' exprOrDataType ')' yP_TICK '(' expr ')' { $$ = new AstCast{$1, $7, VFlagChildDType{}, diff --git a/test_regress/t/t_covergroup_unsup.out b/test_regress/t/t_covergroup_unsup.out index 2f130f11a..7394aecf4 100644 --- a/test_regress/t/t_covergroup_unsup.out +++ b/test_regress/t/t_covergroup_unsup.out @@ -405,11 +405,8 @@ %Warning-COVERIGN: t/t_covergroup_unsup.v:164:18: Ignoring unsupported: covergroup within class 164 | covergroup cov1 @m_z; | ^~~~ -%Error: t/t_covergroup_unsup.v:169:28: syntax error, unexpected '=', expecting IDENTIFIER or do or final or randomize +%Error: t/t_covergroup_unsup.v:169:23: Can't find definition of variable: 'cov1' 169 | function new(); cov1 = new; endfunction - | ^ + | ^~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: Internal Error: t/t_covergroup_unsup.v:160:4: ../V3ParseSym.h:#: Symbols suggest ending FUNC 'new' but parser thinks ending CLASS 'CgCls' - 160 | class CgCls; - | ^~~~~ - ... This fatal error may be caused by the earlier error(s); resolve those first. +%Error: Exiting due to diff --git a/test_regress/t/t_dist_warn_coverage.py b/test_regress/t/t_dist_warn_coverage.py index fdea18d15..4f338cf12 100755 --- a/test_regress/t/t_dist_warn_coverage.py +++ b/test_regress/t/t_dist_warn_coverage.py @@ -53,11 +53,14 @@ for s in [ 'Illegal +: or -: select; type already selected, or bad dimension: ', 'Illegal bit or array select; type already selected, or bad dimension: ', 'Illegal range select; type already selected, or bad dimension: ', + 'Interface port ', + 'Interface port declaration ', 'Modport item is not a function/task: ', 'Modport item is not a variable: ', 'Modport item not found: ', 'Modport not referenced as .', 'Modport not referenced from underneath an interface: ', + 'Non-interface used as an interface: ', 'Parameter type pin value isn\'t a type: Param ', 'Parameter type variable isn\'t a type: Param ', 'Pattern replication value of 0 is not legal.', diff --git a/test_regress/t/t_inst_paren_bad.out b/test_regress/t/t_inst_paren_bad.out index 0413a0278..f50638471 100644 --- a/test_regress/t/t_inst_paren_bad.out +++ b/test_regress/t/t_inst_paren_bad.out @@ -1,8 +1,3 @@ -%Error: t/t_inst_paren_bad.v:11:4: Non-interface used as an interface: 'sub' - : ... Perhaps intended an instantiation but are missing parenthesis (IEEE 1800-2023 23.3.2)? - 11 | sub sub_inst; - | ^~~ - ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Warning-MULTITOP: t/t_inst_paren_bad.v:10:8: Multiple top level modules : ... Suggest see manual; fix the duplicates, or use --top-module to select top. ... For warning description see https://verilator.org/warn/MULTITOP?v=latest @@ -13,4 +8,8 @@ : ... Top module 't' 10 | module t( ); | ^ +%Error: t/t_inst_paren_bad.v:11:4: Can't find typedef/interface: 'sub' + 11 | sub sub_inst; + | ^~~ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error: Exiting due to diff --git a/test_regress/t/t_interface_missing_bad.out b/test_regress/t/t_interface_missing_bad.out index 01956743a..2b5585d4b 100644 --- a/test_regress/t/t_interface_missing_bad.out +++ b/test_regress/t/t_interface_missing_bad.out @@ -1,17 +1,11 @@ -%Error: t/t_interface_missing_bad.v:14:13: Pin is not an in/out/inout/interface: 'foo' - 14 | foo_intf foo - | ^~~ - ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error: t/t_interface_missing_bad.v:14:4: Can't find typedef/interface: 'foo_intf' 14 | foo_intf foo | ^~~~~~~~ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error: t/t_interface_missing_bad.v:20:4: Cannot find file containing interface: 'foo_intf' 20 | foo_intf the_foo (); | ^~~~~~~~ %Error: t/t_interface_missing_bad.v:25:15: Found definition of 'the_foo' as a CELL but expected a variable 25 | .foo (the_foo) | ^~~~~~~ -%Error: t/t_interface_missing_bad.v:25:10: Instance attempts to connect to 'foo', but it is a variable - 25 | .foo (the_foo) - | ^~~ %Error: Exiting due to diff --git a/test_regress/t/t_interface_paren_missing_bad.out b/test_regress/t/t_interface_paren_missing_bad.out index ebea7deaf..f86122e68 100644 --- a/test_regress/t/t_interface_paren_missing_bad.out +++ b/test_regress/t/t_interface_paren_missing_bad.out @@ -1,6 +1,6 @@ -%Error: t/t_interface_paren_missing_bad.v:13:9: Interface port declaration 'intf_i' doesn't have corresponding port +%Error: t/t_interface_paren_missing_bad.v:13:4: Parent instance's interface is not found: 'intf' : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? 13 | intf intf_i; - | ^~~~~~ + | ^~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error: Exiting due to diff --git a/test_regress/t/t_interface_top_bad.out b/test_regress/t/t_interface_top_bad.out index bd8213cec..e90e95137 100644 --- a/test_regress/t/t_interface_top_bad.out +++ b/test_regress/t/t_interface_top_bad.out @@ -3,6 +3,7 @@ | ^~~~~~ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest %Error: t/t_interface_top_bad.v:17:4: Parent instance's interface is not found: 'ifc' + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? 17 | ifc.counter_mp c_data | ^~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. diff --git a/test_regress/t/t_interface_typedef.out b/test_regress/t/t_interface_typedef.out index 35d9a3031..ab677162e 100644 --- a/test_regress/t/t_interface_typedef.out +++ b/test_regress/t/t_interface_typedef.out @@ -2,8 +2,4 @@ 46 | typedef ifc_if.struct_t struct_t; | ^~~~~~~ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error: t/t_interface_typedef.v:51:16: syntax error, unexpected IDENTIFIER - 51 | struct_t substruct; - | ^~~~~~~~~ - ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error: Exiting due to diff --git a/test_regress/t/t_interface_typo_bad.out b/test_regress/t/t_interface_typo_bad.out index 6e24ad530..e08823cfa 100644 --- a/test_regress/t/t_interface_typo_bad.out +++ b/test_regress/t/t_interface_typo_bad.out @@ -1,4 +1,5 @@ %Error: t/t_interface_typo_bad.v:14:4: Parent instance's interface is not found: 'foo_intf' + : ... Perhaps intended an interface instantiation but are missing parenthesis (IEEE 1800-2023 25.3)? 14 | foo_intf foo | ^~~~~~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. diff --git a/test_regress/t/t_lint_implicit_type_bad.out b/test_regress/t/t_lint_implicit_type_bad.out index 80984654a..3d0241a7e 100644 --- a/test_regress/t/t_lint_implicit_type_bad.out +++ b/test_regress/t/t_lint_implicit_type_bad.out @@ -1,5 +1,11 @@ -%Error: t/t_lint_implicit_type_bad.v:15:11: syntax error, unexpected IDENTIFIER-for-type +%Error: t/t_lint_implicit_type_bad.v:15:11: Data type used where a non-data type is expected: 'imp_typedef_conflict' 15 | assign imp_typedef_conflict = 1'b1; | ^~~~~~~~~~~~~~~~~~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. +%Error: t/t_lint_implicit_type_bad.v:16:11: Data type used where a non-data type is expected: 'imp_Cls_conflict' + 16 | assign imp_Cls_conflict = 1'b1; + | ^~~~~~~~~~~~~~~~ +%Error: t/t_lint_implicit_type_bad.v:17:11: Data type used where a non-data type is expected: 'imp_PARAM_conflict' + 17 | assign imp_PARAM_conflict = 1'b1; + | ^~~~~~~~~~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_lint_implicit_type_bad.py b/test_regress/t/t_lint_implicit_type_bad.py index e15e088e1..ff290aea9 100755 --- a/test_regress/t/t_lint_implicit_type_bad.py +++ b/test_regress/t/t_lint_implicit_type_bad.py @@ -12,7 +12,7 @@ import vltest_bootstrap test.scenarios('vlt') # --debug-check adds extra internal message, otherwise golden log would vary -test.lint(verilator_flags2=["--lint-only --debug-check -Wall -Wno-DECLFILENAME"], +test.lint(verilator_flags2=["--lint-only --no-debug-check -Wall -Wno-DECLFILENAME"], fails=True, expect_filename=test.golden_filename) diff --git a/test_regress/t/t_lint_import_name2_bad.out b/test_regress/t/t_lint_import_name2_bad.out index 88ed7907c..30fd80a44 100644 --- a/test_regress/t/t_lint_import_name2_bad.out +++ b/test_regress/t/t_lint_import_name2_bad.out @@ -1,7 +1,3 @@ -%Error-PKGNODECL: t/t_lint_import_name2_bad.v:7:8: Package/class 'missing' not found, and needs to be predeclared (IEEE 1800-2023 26.3) - 7 | import missing::sigs; - | ^~~~~~~ - ... For error description see https://verilator.org/warn/PKGNODECL?v=latest %Error: t/t_lint_import_name2_bad.v:7:8: Importing from missing package 'missing' 7 | import missing::sigs; | ^~~~~~~ diff --git a/test_regress/t/t_lint_pkg_colon_bad.out b/test_regress/t/t_lint_pkg_colon_bad.out index 69ae72f72..b0e76fd25 100644 --- a/test_regress/t/t_lint_pkg_colon_bad.out +++ b/test_regress/t/t_lint_pkg_colon_bad.out @@ -1,9 +1,5 @@ -%Error-PKGNODECL: t/t_lint_pkg_colon_bad.v:7:17: Package/class 'mispkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3) - 7 | module t (input mispkg::foo_t a); - | ^~~~~~ - ... For error description see https://verilator.org/warn/PKGNODECL?v=latest -%Error: t/t_lint_pkg_colon_bad.v:7:25: syntax error, unexpected IDENTIFIER, expecting IDENTIFIER-for-type - 7 | module t (input mispkg::foo_t a); - | ^~~~~ +%Error: t/t_lint_pkg_colon_bad.v:8:8: syntax error, unexpected IDENTIFIER-::, expecting IDENTIFIER or do or final or randomize + 8 | reg mispkgb::bar_t b; + | ^~~~~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error: Exiting due to diff --git a/test_regress/t/t_lint_pkgnodecl_bad.out b/test_regress/t/t_lint_pkgnodecl_bad.out deleted file mode 100644 index 56072a8d4..000000000 --- a/test_regress/t/t_lint_pkgnodecl_bad.out +++ /dev/null @@ -1,5 +0,0 @@ -%Error-PKGNODECL: t/t_lint_pkgnodecl_bad.v:8:12: Package/class 'Pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3) - 8 | initial Pkg::hello(); - | ^~~ - ... For error description see https://verilator.org/warn/PKGNODECL?v=latest -%Error: Exiting due to diff --git a/test_regress/t/t_lint_pkgnodecl_bad.py b/test_regress/t/t_lint_pkgnodecl_bad.py deleted file mode 100755 index 77102e664..000000000 --- a/test_regress/t/t_lint_pkgnodecl_bad.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python3 -# DESCRIPTION: Verilator: Verilog Test driver/expect definition -# -# Copyright 2024 by Wilson Snyder. This program is free software; you -# can redistribute it and/or modify it under the terms of either the GNU -# Lesser General Public License Version 3 or the Perl Artistic License -# Version 2.0. -# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 - -import vltest_bootstrap - -test.scenarios('linter') - -root = ".." - -if not os.path.exists(root + "/.git"): - test.skip("Not in a git repository") - -test.lint(fails=True, expect_filename=test.golden_filename) - -test.extract(in_filename=test.top_filename, - out_filename=root + "/docs/gen/ex_PKGNODECL_faulty.rst", - lines="7-12") - -test.extract(in_filename=test.golden_filename, - out_filename=root + "/docs/gen/ex_PKGNODECL_msg.rst", - lines="1") - -test.passes() diff --git a/test_regress/t/t_lint_pkgnodecl_bad.v b/test_regress/t/t_lint_pkgnodecl_bad.v deleted file mode 100644 index ee8248f78..000000000 --- a/test_regress/t/t_lint_pkgnodecl_bad.v +++ /dev/null @@ -1,12 +0,0 @@ -// DESCRIPTION: Verilator: Verilog Test module -// -// This file ONLY is placed under the Creative Commons Public Domain, for -// any use, without warranty, 2012 by Wilson Snyder. -// SPDX-License-Identifier: CC0-1.0 - -module t; - initial Pkg::hello(); //<--- Warning -endmodule -package Pkg; - function void hello(); endfunction -endpackage diff --git a/test_regress/t/t_no_std_bad.out b/test_regress/t/t_no_std_bad.out index 270ff073b..f4b668c23 100644 --- a/test_regress/t/t_no_std_bad.out +++ b/test_regress/t/t_no_std_bad.out @@ -1,7 +1,3 @@ -%Error-PKGNODECL: t/t_no_std_bad.v:9:11: Package/class 'std' not found, and needs to be predeclared (IEEE 1800-2023 26.3) - 9 | import std::*; - | ^~~ - ... For error description see https://verilator.org/warn/PKGNODECL?v=latest %Error: t/t_no_std_bad.v:9:11: Importing from missing package 'std' 9 | import std::*; | ^~~ diff --git a/test_regress/t/t_package_alone_bad.out b/test_regress/t/t_package_alone_bad.out index bd58349f1..8a39e026f 100644 --- a/test_regress/t/t_package_alone_bad.out +++ b/test_regress/t/t_package_alone_bad.out @@ -1,5 +1,5 @@ -%Error-PKGNODECL: t/t_package_alone_bad.v:7:8: Package/class 'pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3) +%Error: t/t_package_alone_bad.v:7:13: Export package not found: 'pkg' 7 | export pkg::something; - | ^~~ - ... For error description see https://verilator.org/warn/PKGNODECL?v=latest + | ^~~~~~~~~ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error: Exiting due to diff --git a/test_regress/t/t_parse_sync_bad2.out b/test_regress/t/t_parse_sync_bad2.out index fdfd58413..5fa429099 100644 --- a/test_regress/t/t_parse_sync_bad2.out +++ b/test_regress/t/t_parse_sync_bad2.out @@ -1,8 +1,24 @@ -%Error: t/t_parse_sync_bad2.v:17:16: syntax error, unexpected IDENTIFIER - 17 | Invalid1 invalid1; - | ^~~~~~~~ +%Error: t/t_parse_sync_bad2.v:9:15: Can't find typedef/interface: 'unknown' + 9 | typedef unknown defu; + | ^~~~~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_parse_sync_bad2.v:20:16: syntax error, unexpected IDENTIFIER +%Error: t/t_parse_sync_bad2.v:17:7: Can't find typedef/interface: 'Invalid1' + 17 | Invalid1 invalid1; + | ^~~~~~~~ +%Error-UNSUPPORTED: t/t_parse_sync_bad2.v:18:12: Unsupported: Multiple '::' package/class reference + 18 | pkg::cls::defi valid1; + | ^~~ + ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest +%Error: t/t_parse_sync_bad2.v:18:17: Can't find typedef/interface: 'defi' + 18 | pkg::cls::defi valid1; + | ^~~~ +%Error-UNSUPPORTED: t/t_parse_sync_bad2.v:19:12: Unsupported: Multiple '::' package/class reference + 19 | pkg::cls::defu valid2; + | ^~~ +%Error: t/t_parse_sync_bad2.v:19:17: Can't find typedef/interface: 'defu' + 19 | pkg::cls::defu valid2; + | ^~~~ +%Error: t/t_parse_sync_bad2.v:20:7: Can't find typedef/interface: 'Invalid2' 20 | Invalid2 invalid2; - | ^~~~~~~~ + | ^~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_pp_circ_subst_bad.out b/test_regress/t/t_pp_circ_subst_bad.out index 6553eeaa3..d45c9c044 100644 --- a/test_regress/t/t_pp_circ_subst_bad.out +++ b/test_regress/t/t_pp_circ_subst_bad.out @@ -1,4 +1,4 @@ %Error: t/t_pp_circ_subst_bad.v:8:80001: Too many preprocessor tokens on a line (>40000); perhaps recursive `define ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_pp_circ_subst_bad.v:8:1: syntax error, unexpected IDENTIFIER +%Error: t/t_pp_circ_subst_bad.v:8:5: syntax error, unexpected IDENTIFIER-for-type, expecting IDENTIFIER or do or final or randomize %Error: Exiting due to diff --git a/test_regress/t/t_pp_circ_subst_bad2.out b/test_regress/t/t_pp_circ_subst_bad2.out index e6a97d6d1..5af9aac7f 100644 --- a/test_regress/t/t_pp_circ_subst_bad2.out +++ b/test_regress/t/t_pp_circ_subst_bad2.out @@ -1,4 +1,4 @@ %Error: t/t_pp_circ_subst_bad.v:8:40002: Too many preprocessor tokens on a line (>20000); perhaps recursive `define ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_pp_circ_subst_bad.v:8:1: syntax error, unexpected IDENTIFIER +%Error: t/t_pp_circ_subst_bad.v:8:5: syntax error, unexpected IDENTIFIER-for-type, expecting IDENTIFIER or do or final or randomize %Error: Exiting due to diff --git a/test_regress/t/t_preproc_inc_bad.out b/test_regress/t/t_preproc_inc_bad.out index 468822a47..e556a2571 100644 --- a/test_regress/t/t_preproc_inc_bad.out +++ b/test_regress/t/t_preproc_inc_bad.out @@ -1,4 +1,4 @@ -%Error: t/t_preproc_inc_inc_bad.vh:11:1: syntax error, unexpected endmodule, expecting IDENTIFIER or randomize +%Error: t/t_preproc_inc_inc_bad.vh:11:1: syntax error, unexpected endmodule, expecting '(' 11 | endmodule | ^~~~~~~~~ t/t_preproc_inc_bad.v:10:1: ... note: In file included from 't_preproc_inc_bad.v' diff --git a/test_regress/t/t_type_non_type.py b/test_regress/t/t_type_non_type.py new file mode 100755 index 000000000..f989a35fb --- /dev/null +++ b/test_regress/t/t_type_non_type.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_type_non_type.v b/test_regress/t/t_type_non_type.v new file mode 100644 index 000000000..730f1c314 --- /dev/null +++ b/test_regress/t/t_type_non_type.v @@ -0,0 +1,49 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// Use this file as a template for submitting bugs, etc. +// This module takes a single clock input, and should either +// $write("*-* All Finished *-*\n"); +// $finish; +// on success, or $stop. +// +// The code as shown applies a random vector to the Test +// module, then calculates a CRC on the Test module's outputs. +// +// **If you do not wish for your code to be released to the public +// please note it here, otherwise:** +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +class Cls; +endclass + +package Pkg; + // Issue #2956 + typedef string STYPE; + typedef string line; + task automatic testf; + inout STYPE line; + endtask +endpackage + +module t; + localparam type T = Cls; + + // Issue #2412 + typedef T this_thing; // this_thing now a type + + function T newer(); + T this_thing; // this_thing now a class reference + this_thing = new; + return this_thing; + endfunction + + initial begin + Cls c; + c = newer(); + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule diff --git a/test_regress/t/t_vams_kwd_bad.out b/test_regress/t/t_vams_kwd_bad.out index d10e51e87..0cea02097 100644 --- a/test_regress/t/t_vams_kwd_bad.out +++ b/test_regress/t/t_vams_kwd_bad.out @@ -2,7 +2,7 @@ 12 | int above; | ^~~~~ ... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest -%Error: t/t_vams_kwd_bad.v:12:13: syntax error, unexpected ';', expecting IDENTIFIER or randomize +%Error: t/t_vams_kwd_bad.v:12:13: syntax error, unexpected ';', expecting '(' 12 | int above; | ^ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.