mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Add error on zero/negative unpacked dimensions (#1642).
This commit is contained in:
+10
-4
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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}; }
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user