Add error on zero/negative unpacked dimensions (#1642).

This commit is contained in:
Wilson Snyder
2025-09-21 09:41:58 -04:00
parent ed380f08fe
commit 53b8a5b027
15 changed files with 86 additions and 24 deletions
+10 -4
View File
@@ -2720,7 +2720,7 @@ public:
// === AstNodeRange ===
class AstBracketRange final : public AstNodeRange {
// Parser only concept "[lhsp]", an AstUnknownRange, QueueRange or Range,
// Parser only concept C-style "[lhsp]", an AstUnknownRange, QueueRange or Range,
// unknown until lhsp type is determined
// @astgen op1 := elementsp : AstNode<AstNodeExpr|AstNodeDType>
public:
@@ -2740,9 +2740,11 @@ class AstRange final : public AstNodeRange {
// Range specification, for use under variables and cells
// @astgen op1 := leftp : AstNodeExpr
// @astgen op2 := rightp : AstNodeExpr
const bool m_fromBracket = false; // From C-style '[x]' declaration
public:
AstRange(FileLine* fl, AstNodeExpr* leftp, AstNodeExpr* rightp)
: ASTGEN_SUPER_Range(fl) {
AstRange(FileLine* fl, AstNodeExpr* leftp, AstNodeExpr* rightp, bool fromBracket = false)
: ASTGEN_SUPER_Range(fl)
, m_fromBracket{fromBracket} {
this->leftp(leftp);
this->rightp(rightp);
}
@@ -2766,7 +2768,11 @@ public:
void dump(std::ostream& str) const override;
void dumpJson(std::ostream& str) const override;
virtual string emitC() { V3ERROR_NA_RETURN(""); }
bool sameNode(const AstNode* /*samep*/) const override { return true; }
bool sameNode(const AstNode* samep) const override {
const AstRange* const asamep = VN_DBG_AS(samep, Range);
return fromBracket() == asamep->fromBracket();
}
bool fromBracket() const { return m_fromBracket; }
};
class AstUnsizedRange final : public AstNodeRange {
// Unsized range specification, for open arrays
+2
View File
@@ -2217,10 +2217,12 @@ void AstNodeRange::dump(std::ostream& str) const { this->AstNode::dump(str); }
void AstNodeRange::dumpJson(std::ostream& str) const { dumpJsonGen(str); }
void AstRange::dump(std::ostream& str) const {
this->AstNodeRange::dump(str);
if (fromBracket()) str << " [FB]";
if (ascending()) str << " [ASCENDING]";
}
void AstRange::dumpJson(std::ostream& str) const {
dumpJsonBoolFunc(str, ascending);
dumpJsonBoolFunc(str, fromBracket);
dumpJsonGen(str);
}
void AstParamTypeDType::dump(std::ostream& str) const {
+11 -3
View File
@@ -961,7 +961,14 @@ class WidthVisitor final : public VNVisitor {
if (m_vup->prelim()) {
// Don't need to iterate because V3Const already constified
const int width = nodep->elementsConst();
if (width > (1 << 28)) {
if (nodep->fromBracket() && nodep->leftConst() > nodep->rightConst()) {
// From a C-Style '[size]' declaration, due to range handling a '[-1]'
// will get transformed to look like a '[0:1]', instead report as error
// now we know the datatype is used
nodep->v3error("Size of range is '["
<< (-width + 2)
<< "]', must be positive integer (IEEE 1800-2023 7.4.2)");
} else if (width > (1 << 28)) {
nodep->v3error("Width of bit range is huge; vector of over 1 billion bits: 0x"
<< std::hex << width << std::dec);
}
@@ -1921,7 +1928,7 @@ class WidthVisitor final : public VNVisitor {
// Cleanup array size
userIterateAndNext(nodep->rangep(), WidthVP{SELF, BOTH}.p());
nodep->dtypep(nodep); // The array itself, not subDtype
if (auto* const adtypep = VN_CAST(nodep, UnpackArrayDType)) {
if (AstUnpackArrayDType* const adtypep = VN_CAST(nodep, UnpackArrayDType)) {
// Historically array elements have width of the ref type not the full array
nodep->widthFromSub(nodep->subDTypep());
if (nodep->subDTypep()->skipRefp()->isCompound()) adtypep->isCompound(true);
@@ -1964,7 +1971,8 @@ class WidthVisitor final : public VNVisitor {
nodep->fileline(), VFlagChildDType{}, childp,
new AstRange{nodep->fileline(), new AstConst(elementsp->fileline(), 0),
new AstSub{elementsNewFl, VN_AS(elementsp, NodeExpr),
new AstConst(elementsNewFl, 1)}}};
new AstConst(elementsNewFl, 1)},
true}};
}
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
+1 -1
View File
@@ -3189,7 +3189,7 @@ instRangeList<nodeRangep>:
instRange<nodeRangep>:
'[' constExpr ']'
{ $$ = new AstRange{$1, new AstConst{$1, 0}, new AstSub{$1, $2, new AstConst{$1, 1}}}; }
{ $$ = new AstRange{$1, new AstConst{$1, 0}, new AstSub{$1, $2, new AstConst{$1, 1}}, true}; }
| '[' constExpr ':' constExpr ']'
{ $$ = new AstRange{$1, $2, $4}; }
;