diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 9790d17e8..def288069 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -2484,10 +2484,14 @@ class WidthVisitor final : public VNVisitor { nodep->refDTypep(iterateEditMoveDTypep(nodep, nodep->subDTypep())); nodep->dtypep(nodep); AstNodeDType* basicp = nodep->dtypep()->skipRefp()->basicp(); - if (!dtypeIsIntAtomOrVecRecurse(nodep->subDTypep())) { + AstNodeDType* const badDtp = dtypeNotIntAtomOrVecRecurse(nodep->subDTypep()); + if (badDtp) { nodep->v3error( - "Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19), not " - << nodep->subDTypep()->prettyDTypeNameQ()); + "Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19)\n" + << nodep->warnContextPrimary() << '\n' + << badDtp->warnOther() << "... Location of failing data type " + << badDtp->prettyDTypeNameQ() << '\n' + << badDtp->warnContextSecondary()); basicp = nodep->findSigned32DType()->basicp(); nodep->refDTypep(basicp); } @@ -8310,23 +8314,19 @@ class WidthVisitor final : public VNVisitor { if (nodep->subDTypep()) return hasOpenArrayIterateDType(nodep->subDTypep()->skipRefp()); return false; } - bool dtypeIsIntAtomOrVecRecurse(AstNodeDType* nodep, bool ranged = false) { + AstNodeDType* dtypeNotIntAtomOrVecRecurse(AstNodeDType* nodep, bool ranged = false) { + // If node is _not_ integer or atomic, return node that makes it fail nodep = nodep->skipRefToEnump(); if (AstBasicDType* const dtp = VN_CAST(nodep, BasicDType)) { - if (ranged && (!dtp->isBitLogic() || dtp->isRanged())) { - UINFO(9, "dtypeIsIntAtomOrVecRecurse false at " << nodep); - return false; // Packed when already packed - } - if (dtp->keyword().isIntNumeric()) return true; + if (ranged && (!dtp->isBitLogic() || dtp->isRanged())) + return dtp; // Packed when already packed + if (dtp->keyword().isIntNumeric()) return nullptr; + return dtp; } else if (AstPackArrayDType* const dtp = VN_CAST(nodep, PackArrayDType)) { - if (ranged) { - UINFO(9, "dtypeIsIntAtomOrVecRecurse false at " << nodep); - return false; // Packed when already packed - } - return dtypeIsIntAtomOrVecRecurse(nodep->subDTypep(), true); + if (ranged) return dtp; // Packed when already packed + return dtypeNotIntAtomOrVecRecurse(nodep->subDTypep(), true); } - UINFO(9, "dtypeIsIntAtomOrVecRecurse false at " << nodep); - return false; + return nodep; } //---------------------------------------------------------------------- diff --git a/test_regress/t/t_enum_base_bad.out b/test_regress/t/t_enum_base_bad.out index f57b5e80c..1dff9944a 100644 --- a/test_regress/t/t_enum_base_bad.out +++ b/test_regress/t/t_enum_base_bad.out @@ -1,30 +1,51 @@ -%Error: t/t_enum_base_bad.v:11:11: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19), not 'struct{}t.s_t' +%Error: t/t_enum_base_bad.v:11:11: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19) : ... note: In instance 't' 11 | typedef enum s_t { | ^~~~ + t/t_enum_base_bad.v:9:11: ... Location of failing data type 'struct{}t.s_t' + 9 | typedef struct {int a;} s_t; + | ^~~~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_enum_base_bad.v:16:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19), not 'int[1:0]' +%Error: t/t_enum_base_bad.v:16:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19) : ... note: In instance 't' 16 | enum int_t [1:0] { | ^~~~ -%Error: t/t_enum_base_bad.v:21:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19), not 'bit[1:0][1:0]' + t/t_enum_base_bad.v:15:11: ... Location of failing data type 'int' + 15 | typedef int int_t; + | ^~~ +%Error: t/t_enum_base_bad.v:21:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19) : ... note: In instance 't' 21 | enum d2_t { | ^~~~ -%Error: t/t_enum_base_bad.v:25:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19), not 'logic[1:0][1:0]' + t/t_enum_base_bad.v:20:11: ... Location of failing data type 'bit[1:0]' + 20 | typedef bit [1:0][1:0] d2_t; + | ^~~ +%Error: t/t_enum_base_bad.v:25:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19) : ... note: In instance 't' 25 | enum logic [1:0][1:0] { | ^~~~ -%Error: t/t_enum_base_bad.v:30:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19), not 'struct{}t.str_t' + t/t_enum_base_bad.v:25:8: ... Location of failing data type 'logic[1:0]' + 25 | enum logic [1:0][1:0] { + | ^~~~~ +%Error: t/t_enum_base_bad.v:30:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19) : ... note: In instance 't' 30 | enum str_t { | ^~~~ -%Error: t/t_enum_base_bad.v:35:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19), not 'enum{}t.enum_t' + t/t_enum_base_bad.v:29:11: ... Location of failing data type 'struct{}t.str_t' + 29 | typedef struct packed {int x;} str_t; + | ^~~~~~ +%Error: t/t_enum_base_bad.v:35:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19) : ... note: In instance 't' 35 | enum enum_t { | ^~~~ -%Error: t/t_enum_base_bad.v:40:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19), not 'logic$[1:0]' + t/t_enum_base_bad.v:34:11: ... Location of failing data type 'enum{}t.enum_t' + 34 | typedef enum {ENUM_VAL} enum_t; + | ^~~~ +%Error: t/t_enum_base_bad.v:40:3: Enum data type must be an integer atom or vector type (IEEE 1800-2023 6.19) : ... note: In instance 't' 40 | enum array2_t { | ^~~~ + t/t_enum_base_bad.v:39:25: ... Location of failing data type 'logic$[1:0]' + 39 | typedef logic array2_t[1:0]; + | ^ %Error: Exiting due to