<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:Wingdings;
panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
{font-family:SimSun;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:SimSun;
panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:"\@SimSun";
panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0in;
margin-bottom:.0001pt;
font-size:11.0pt;
font-family:"Calibri","sans-serif";}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
{mso-style-priority:99;
color:purple;
text-decoration:underline;}
span.EmailStyle17
{mso-style-type:personal-compose;
font-family:"Calibri","sans-serif";
color:windowtext;}
.MsoChpDefault
{mso-style-type:export-only;
font-family:"Calibri","sans-serif";}
@page WordSection1
{size:8.5in 11.0in;
margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
{page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal">Hello, all:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I found a bug in code of tablegen in file record.cpp, line 792, which still exists in latest version 3.4.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">It looks like this:<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">740 Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {<o:p></o:p></p>
<p class="MsoNormal"> switch (getOpcode()) {<o:p></o:p></p>
<p class="MsoNormal"> case CAST: {<o:p></o:p></p>
<p class="MsoNormal"> if (getType()->getAsString() == "string") {<o:p></o:p></p>
<p class="MsoNormal"> if (StringInit *LHSs = dyn_cast<StringInit>(LHS))<o:p></o:p></p>
<p class="MsoNormal"> return LHSs;<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> if (DefInit *LHSd = dyn_cast<DefInit>(LHS))<o:p></o:p></p>
<p class="MsoNormal"> return StringInit::get(LHSd->getDef()->getName());<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> if (IntInit *LHSi = dyn_cast<IntInit>(LHS))<o:p></o:p></p>
<p class="MsoNormal"> return StringInit::get(LHSi->getAsString());<o:p></o:p></p>
<p class="MsoNormal"> } else {<o:p></o:p></p>
<p class="MsoNormal"> if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) {<o:p></o:p></p>
<p class="MsoNormal"> std::string Name = LHSs->getValue();<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> // From TGParser::ParseIDValue<o:p></o:p></p>
<p class="MsoNormal"><span style="color:red">757 if (CurRec) { </span><span style="font-family:Wingdings;color:red">ß</span><span style="color:red"> we check CurRec here, but this check doesn’t cover line 792<o:p></o:p></span></p>
<p class="MsoNormal"> if (const RecordVal *RV = CurRec->getValue(Name)) {<o:p></o:p></p>
<p class="MsoNormal"> if (RV->getType() != getType())<o:p></o:p></p>
<p class="MsoNormal"> PrintFatalError("type mismatch in cast");<o:p></o:p></p>
<p class="MsoNormal"> return VarInit::get(Name, RV->getType());<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name,<o:p></o:p></p>
<p class="MsoNormal"> ":");<o:p></o:p></p>
<p class="MsoNormal"> <o:p></o:p></p>
<p class="MsoNormal"> if (CurRec->isTemplateArg(TemplateArgName)) {<o:p></o:p></p>
<p class="MsoNormal"> const RecordVal *RV = CurRec->getValue(TemplateArgName);<o:p></o:p></p>
<p class="MsoNormal"> assert(RV && "Template arg doesn't exist??");<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> if (RV->getType() != getType())<o:p></o:p></p>
<p class="MsoNormal"> PrintFatalError("type mismatch in cast");<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> return VarInit::get(TemplateArgName, RV->getType());<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> if (CurMultiClass) {<o:p></o:p></p>
<p class="MsoNormal"> Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::");<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> if (CurMultiClass->Rec.isTemplateArg(MCName)) {<o:p></o:p></p>
<p class="MsoNormal"> const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);<o:p></o:p></p>
<p class="MsoNormal"> assert(RV && "Template arg doesn't exist??");<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> if (RV->getType() != getType())<o:p></o:p></p>
<p class="MsoNormal"> PrintFatalError("type mismatch in cast");<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> return VarInit::get(MCName, RV->getType());<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><span style="color:red">792 if (Record *D = (CurRec->getRecords()).getDef(Name))
</span><span style="font-family:Wingdings;color:red">ß</span><span style="color:red"> if CurRec is NULL, it will be in trouble<o:p></o:p></span></p>
<p class="MsoNormal"> return DefInit::get(D);<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> PrintFatalError(CurRec->getLoc(),<o:p></o:p></p>
<p class="MsoNormal"> "Undefined reference:'" + Name + "'\n");<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> break;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> case HEAD: {<o:p></o:p></p>
<p class="MsoNormal"> if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {<o:p></o:p></p>
<p class="MsoNormal"> if (LHSl->getSize() == 0) {<o:p></o:p></p>
<p class="MsoNormal"> assert(0 && "Empty list in car");<o:p></o:p></p>
<p class="MsoNormal"> return 0;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> return LHSl->getElement(0);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> break;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> case TAIL: {<o:p></o:p></p>
<p class="MsoNormal"> if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {<o:p></o:p></p>
<p class="MsoNormal"> if (LHSl->getSize() == 0) {<o:p></o:p></p>
<p class="MsoNormal"> assert(0 && "Empty list in cdr");<o:p></o:p></p>
<p class="MsoNormal"> return 0;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> // Note the +1. We can't just pass the result of getValues()<o:p></o:p></p>
<p class="MsoNormal"> // directly.<o:p></o:p></p>
<p class="MsoNormal"> ArrayRef<Init *>::iterator begin = LHSl->getValues().begin()+1;<o:p></o:p></p>
<p class="MsoNormal"> ArrayRef<Init *>::iterator end = LHSl->getValues().end();<o:p></o:p></p>
<p class="MsoNormal"> ListInit *Result =<o:p></o:p></p>
<p class="MsoNormal"> ListInit::get(ArrayRef<Init *>(begin, end - begin),<o:p></o:p></p>
<p class="MsoNormal"> LHSl->getType());<o:p></o:p></p>
<p class="MsoNormal"> return Result;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> break;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> case EMPTY: {<o:p></o:p></p>
<p class="MsoNormal"> if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {<o:p></o:p></p>
<p class="MsoNormal"> if (LHSl->getSize() == 0) {<o:p></o:p></p>
<p class="MsoNormal"> return IntInit::get(1);<o:p></o:p></p>
<p class="MsoNormal"> } else {<o:p></o:p></p>
<p class="MsoNormal"> return IntInit::get(0);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) {<o:p></o:p></p>
<p class="MsoNormal"> if (LHSs->getValue().empty()) {<o:p></o:p></p>
<p class="MsoNormal"> return IntInit::get(1);<o:p></o:p></p>
<p class="MsoNormal"> } else {<o:p></o:p></p>
<p class="MsoNormal"> return IntInit::get(0);<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"> break;<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> }<o:p></o:p></p>
<p class="MsoNormal"> return const_cast<UnOpInit *>(this);<o:p></o:p></p>
<p class="MsoNormal">}<o:p></o:p></p>
</div>
</body>
</html>