diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index 54af664b8..6c6879e4c 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -233,6 +233,7 @@ class SliceVisitor : public AstNVisitor { if (!selp) { nodep->user1p(fromp->castVarRef()); selp = NULL; + break; } else { fromp = selp->fromp(); if (fromp) ++dim; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index aba6159e6..e7a43862b 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -359,10 +359,32 @@ private: } } virtual void visit(AstRange* nodep, AstNUser* vup) { - // If there's an edit, then processes the edit'ee (can't just rely on iterateChildren because sometimes we for(...) here ourself // Real: Not allowed // Signed: unsigned output, input either - AstNode* selp = V3Width::widthSelNoIterEdit(nodep); if (selp!=nodep) { nodep=NULL; selp->iterate(*this,vup); return; } + // Convert all range values to constants + UINFO(6,"RANGE "<msbp()); // May relink pointed to node + V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node + checkConstantOrReplace(nodep->msbp(), "MSB of bit range isn't a constant"); + checkConstantOrReplace(nodep->lsbp(), "LSB of bit range isn't a constant"); + int msb = nodep->msbConst(); + int lsb = nodep->lsbConst(); + if (msbbackp()->castRange()) huntbackp=huntbackp->backp(); + if (huntbackp->backp()->castArrayDType()) { + } else { + // Little endian bits are legal, just remember to swap + // Warning is in V3Width to avoid false warnings when in "off" generate if's + nodep->littleEndian(!nodep->littleEndian()); + } + // Internally we'll always have msb() be the greater number + // We only need to correct when doing [] AstSel extraction, + // and when tracing the vector. + nodep->msbp()->swapWith(nodep->lsbp()); + } if (vup->c()->prelim()) { nodep->msbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->lsbp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); @@ -514,8 +536,7 @@ private: <<" bits."); if (!nodep->fileline()->warnIsOff(V3ErrorCode::WIDTH)) { UINFO(1," Related node: "<varp()<dtypep()<bitp(),selwidth,selwidth,true); @@ -2337,6 +2358,15 @@ private: // index is NOT wide enough, you do not sign extend, but always zero extend. return (nodep->castArraySel() || nodep->castSel()); } + void checkConstantOrReplace(AstNode* nodep, const string& message) { + // See also V3WidthSel::checkConstantOrReplace + // Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us! + if (!nodep->castConst()) { + nodep->v3error(message); + nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Unsized32(), 1)); + pushDeletep(nodep); nodep=NULL; + } + } public: // CONSTUCTORS diff --git a/src/V3WidthSel.cpp b/src/V3WidthSel.cpp index 14e14a435..97de8029f 100644 --- a/src/V3WidthSel.cpp +++ b/src/V3WidthSel.cpp @@ -65,6 +65,7 @@ private: } void checkConstantOrReplace(AstNode* nodep, const string& message) { + // See also V3Width::checkConstantOrReplace // Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us! if (!nodep->castConst()) { nodep->v3error(message); @@ -186,33 +187,6 @@ private: // VISITORS // If adding new visitors, insure V3Width's visit(TYPE) calls into here - virtual void visit(AstRange* nodep, AstNUser*) { - // Convert all range values to constants - UINFO(6,"RANGE "<msbp()); // May relink pointed to node - V3Const::constifyParamsEdit(nodep->lsbp()); // May relink pointed to node - checkConstantOrReplace(nodep->msbp(), "MSB of bit range isn't a constant"); - checkConstantOrReplace(nodep->lsbp(), "LSB of bit range isn't a constant"); - int msb = nodep->msbConst(); - int lsb = nodep->lsbConst(); - if (msbbackp()->castRange()) huntbackp=huntbackp->backp(); - if (huntbackp->backp()->castArrayDType()) { - } else { - // Little endian bits are legal, just remember to swap - // Warning is in V3Width to avoid false warnings when in "off" generate if's - nodep->littleEndian(!nodep->littleEndian()); - } - // Internally we'll always have msb() be the greater number - // We only need to correct when doing [] AstSel extraction, - // and when tracing the vector. - nodep->msbp()->swapWith(nodep->lsbp()); - } - } - virtual void visit(AstSelBit* nodep, AstNUser*) { UINFO(6,"SELBIT "<=9) nodep->backp()->dumpTree(cout,"-vsbin(-1): ");