Fix pattern assignment to conditionals, bug769.

This commit is contained in:
Wilson Snyder 2014-06-06 21:52:16 -04:00
parent a428e7f618
commit 5da5678e64
3 changed files with 88 additions and 74 deletions

View File

@ -15,7 +15,9 @@ indicates the contributor was also the author of the fix; Thanks!
**** Fix seg-fault with variable of parameterized interface, bug692. [Jie Xu] **** Fix seg-fault with variable of parameterized interface, bug692. [Jie Xu]
**** Fix pattern assignment to arrayed basic type, bug769. [Jie Xu] **** Fix pattern assignment to basic types, bug767. [Jie Xu]
**** Fix pattern assignment to conditionals, bug769. [Jie Xu]
**** Fix shift corner-cases, bug765, bug766, bug768, bug772, bug776. [Clifford Wolf] **** Fix shift corner-cases, bug765, bug766, bug768, bug772, bug776. [Clifford Wolf]

View File

@ -314,8 +314,9 @@ private:
// Just once, do the conditional, expect one bit out. // Just once, do the conditional, expect one bit out.
iterateCheckBool(nodep,"Conditional Test",nodep->condp(),BOTH); iterateCheckBool(nodep,"Conditional Test",nodep->condp(),BOTH);
// Determine sub expression widths only relying on what's in the subops // Determine sub expression widths only relying on what's in the subops
nodep->expr1p()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); // CONTEXT determined, but need data type for pattern assignments
nodep->expr2p()->iterateAndNext(*this,WidthVP(CONTEXT,PRELIM).p()); nodep->expr1p()->iterateAndNext(*this,WidthVP(vup->c()->dtypeNullp(),PRELIM).p());
nodep->expr2p()->iterateAndNext(*this,WidthVP(vup->c()->dtypeNullp(),PRELIM).p());
// Calculate width of this expression. // Calculate width of this expression.
// First call (prelim()) vup->c()->width() is probably zero, so we'll return // First call (prelim()) vup->c()->width() is probably zero, so we'll return
// the size of this subexpression only. // the size of this subexpression only.
@ -1369,31 +1370,35 @@ private:
patp = newpatp; patp = newpatp;
} }
else { else {
patp->v3error("Assignment pattern missed initializing elements: "<<memp->prettyTypeName()); if (!classp->castUnionDType()) {
patp->v3error("Assignment pattern missed initializing elements: "<<memp->prettyTypeName());
}
} }
} else { } else {
patp = it->second; patp = it->second;
} }
// Determine initial values if (patp) {
vdtypep = memp; // Determine initial values
patp->dtypep(memp); vdtypep = memp;
patp->accept(*this,WidthVP(memp,BOTH).p()); patp->dtypep(memp);
// Convert to concat for now patp->accept(*this,WidthVP(memp,BOTH).p());
AstNode* valuep = patp->lhssp()->unlinkFrBack(); // Convert to concat for now
if (valuep->castConst()) { AstNode* valuep = patp->lhssp()->unlinkFrBack();
// Forming a AstConcat will cause problems with unsized (uncommitted sized) constants if (valuep->castConst()) {
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) { // Forming a AstConcat will cause problems with unsized (uncommitted sized) constants
pushDeletep(valuep); valuep=NULL; if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) {
valuep = newp; pushDeletep(valuep); valuep=NULL;
valuep = newp;
}
}
if (!newp) newp = valuep;
else {
AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep);
newp = concatp;
newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(),
concatp->lhsp()->width()+concatp->rhsp()->width(),
nodep->dtypep()->numeric());
} }
}
if (!newp) newp = valuep;
else {
AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep);
newp = concatp;
newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(),
concatp->lhsp()->width()+concatp->rhsp()->width(),
nodep->dtypep()->numeric());
} }
if (newpatp) { pushDeletep(newpatp); newpatp=NULL; } if (newpatp) { pushDeletep(newpatp); newpatp=NULL; }
} }
@ -1424,37 +1429,39 @@ private:
patmap.erase(it); patmap.erase(it);
} }
// Determine initial values if (patp) {
vdtypep = arrayp->subDTypep(); // Determine initial values
// Don't want the RHS an array vdtypep = arrayp->subDTypep();
patp->dtypep(vdtypep); // Don't want the RHS an array
patp->dtypep(vdtypep);
// Determine values - might be another InitArray // Determine values - might be another InitArray
patp->accept(*this,WidthVP(patp->dtypep(),BOTH).p()); patp->accept(*this,WidthVP(patp->dtypep(),BOTH).p());
// Convert to InitArray or constify immediately // Convert to InitArray or constify immediately
AstNode* valuep = patp->lhssp()->unlinkFrBack(); AstNode* valuep = patp->lhssp()->unlinkFrBack();
if (valuep->castConst()) { if (valuep->castConst()) {
// Forming a AstConcat will cause problems with unsized (uncommitted sized) constants // Forming a AstConcat will cause problems with unsized (uncommitted sized) constants
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) { if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) {
pushDeletep(valuep); valuep=NULL; pushDeletep(valuep); valuep=NULL;
valuep = newp; valuep = newp;
}
} }
} if (arrayp->castUnpackArrayDType()) {
if (arrayp->castUnpackArrayDType()) { if (!newp) {
if (!newp) { newp = new AstInitArray(nodep->fileline(), arrayp, valuep);
newp = new AstInitArray(nodep->fileline(), arrayp, valuep); } else {
} else { // We iterate hi()..lo() as that is what packed needs,
// We iterate hi()..lo() as that is what packed needs, // but INITARRAY needs lo() first
// but INITARRAY needs lo() first newp->castInitArray()->initsp()->addHereThisAsNext(valuep);
newp->castInitArray()->initsp()->addHereThisAsNext(valuep); }
} } else { // Packed. Convert to concat for now.
} else { // Packed. Convert to concat for now. if (!newp) newp = valuep;
if (!newp) newp = valuep; else {
else { AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep);
AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep); newp = concatp;
newp = concatp; newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(),
newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(), concatp->lhsp()->width()+concatp->rhsp()->width(),
concatp->lhsp()->width()+concatp->rhsp()->width(), nodep->dtypep()->numeric());
nodep->dtypep()->numeric()); }
} }
} }
if (newpatp) { pushDeletep(newpatp); newpatp=NULL; } if (newpatp) { pushDeletep(newpatp); newpatp=NULL; }
@ -1488,29 +1495,31 @@ private:
patp = it->second; patp = it->second;
patmap.erase(it); patmap.erase(it);
} }
// Determine initial values if (patp) {
vdtypep = nodep->findLogicBoolDType(); // Determine initial values
// Don't want the RHS an array vdtypep = nodep->findLogicBoolDType();
patp->dtypep(vdtypep); // Don't want the RHS an array
// Determine values - might be another InitArray patp->dtypep(vdtypep);
patp->accept(*this,WidthVP(patp->dtypep(),BOTH).p()); // Determine values - might be another InitArray
// Convert to InitArray or constify immediately patp->accept(*this,WidthVP(patp->dtypep(),BOTH).p());
AstNode* valuep = patp->lhssp()->unlinkFrBack(); // Convert to InitArray or constify immediately
if (valuep->castConst()) { AstNode* valuep = patp->lhssp()->unlinkFrBack();
// Forming a AstConcat will cause problems with unsized (uncommitted sized) constants if (valuep->castConst()) {
if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) { // Forming a AstConcat will cause problems with unsized (uncommitted sized) constants
pushDeletep(valuep); valuep=NULL; if (AstNode* newp = WidthCommitVisitor::newIfConstCommitSize(valuep->castConst())) {
valuep = newp; pushDeletep(valuep); valuep=NULL;
valuep = newp;
}
} }
} { // Packed. Convert to concat for now.
{ // Packed. Convert to concat for now. if (!newp) newp = valuep;
if (!newp) newp = valuep; else {
else { AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep);
AstConcat* concatp = new AstConcat(patp->fileline(), newp, valuep); newp = concatp;
newp = concatp; newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(),
newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(), concatp->lhsp()->width()+concatp->rhsp()->width(),
concatp->lhsp()->width()+concatp->rhsp()->width(), nodep->dtypep()->numeric());
nodep->dtypep()->numeric()); }
} }
} }
if (newpatp) { pushDeletep(newpatp); newpatp=NULL; } if (newpatp) { pushDeletep(newpatp); newpatp=NULL; }

View File

@ -67,6 +67,9 @@ module t;
if (tsu.pack2.four.quad1.b2 != 1'b0) $stop; if (tsu.pack2.four.quad1.b2 != 1'b0) $stop;
if (tsu.pack2.four.quad1.b3 != 1'b1) $stop; if (tsu.pack2.four.quad1.b3 != 1'b1) $stop;
// //
tsu = 1'b0 ? '0 : '{pvec: 6'b101011};
if (tsu!=6'b101011) $stop;
//
arr[0] = 6'b101010; arr[0] = 6'b101010;
arr[1] = 6'b010101; arr[1] = 6'b010101;
if (arr[0].four !== 4'b0101) $stop; if (arr[0].four !== 4'b0101) $stop;