<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>