diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 9b7e67920..da8e1e924 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -4203,15 +4203,27 @@ private: // Prep for next fromDtp = fromDtp->subDTypep(); } else if (AstBasicDType* const adtypep = VN_CAST(fromDtp, BasicDType)) { - if (!adtypep->isRanged()) { + if (adtypep->isString()) { + if (varp) { + AstConst* const leftp = new AstConst{fl, AstConst::Signed32{}, 0}; + AstLt* const condp = new AstLt{fl, new AstVarRef{fl, varp, VAccess::READ}, + new AstLenN{fl, fromp->cloneTree(false)}}; + AstAdd* const incp + = new AstAdd{fl, new AstConst{fl, AstConst::Signed32{}, 1}, + new AstVarRef{fl, varp, VAccess::READ}}; + loopp = createForeachLoop(nodep, bodyPointp, varp, leftp, condp, incp); + } + } else if (!adtypep->isRanged()) { argsp->v3error("Illegal to foreach loop on basic '" + fromDtp->prettyTypeName() + "'"); VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep); VL_DO_DANGLING(bodyPointp->deleteTree(), bodyPointp); return; - } - if (varp) { - loopp = createForeachLoopRanged(nodep, bodyPointp, varp, adtypep->declRange()); + } else { + if (varp) { + loopp = createForeachLoopRanged(nodep, bodyPointp, varp, + adtypep->declRange()); + } } // Prep for next fromDtp = nullptr; diff --git a/test_regress/t/t_foreach.v b/test_regress/t/t_foreach.v index c1405a73c..e7f75f0a5 100644 --- a/test_regress/t/t_foreach.v +++ b/test_regress/t/t_foreach.v @@ -18,6 +18,8 @@ module t (/*AUTOARG*/); bit [31:0] depth1_array [0:0]; int oned [3:1]; int twod [3:1][9:8]; + string str1; + string str2; typedef struct packed { reg [1:0] [63:0] subarray; @@ -150,6 +152,20 @@ module t (/*AUTOARG*/); foreach (twod[i, j]); // Null body check + str1 = "abcd"; + str2 = "1234"; + foreach (str1[i]) begin + str2[i] = str1[i]; + end + if (str1 != str2) $stop; + + str1 = ""; + add = 0; + foreach(str1[i]) begin + add++; + end + `checkh(add, 0); + $write("*-* All Finished *-*\n"); $finish; end