[LLVMdev] a code imperfection in tablegen

Hui Wu Z hui.z.wu at ericsson.com
Tue May 13 23:43:13 PDT 2014


Hello, all:

I found a bug in code of tablegen in file record.cpp, line 792, which still exists in latest version 3.4.

It looks like this:

740 Init *UnOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) const {
  switch (getOpcode()) {
  case CAST: {
    if (getType()->getAsString() == "string") {
      if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
        return LHSs;

      if (DefInit *LHSd = dyn_cast<DefInit>(LHS))
        return StringInit::get(LHSd->getDef()->getName());

      if (IntInit *LHSi = dyn_cast<IntInit>(LHS))
        return StringInit::get(LHSi->getAsString());
    } else {
      if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) {
        std::string Name = LHSs->getValue();

        // From TGParser::ParseIDValue
757        if (CurRec) {  <-- we check CurRec here, but this check doesn't cover line 792
          if (const RecordVal *RV = CurRec->getValue(Name)) {
            if (RV->getType() != getType())
              PrintFatalError("type mismatch in cast");
            return VarInit::get(Name, RV->getType());
          }

          Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name,
                                              ":");

          if (CurRec->isTemplateArg(TemplateArgName)) {
            const RecordVal *RV = CurRec->getValue(TemplateArgName);
            assert(RV && "Template arg doesn't exist??");

            if (RV->getType() != getType())
              PrintFatalError("type mismatch in cast");

            return VarInit::get(TemplateArgName, RV->getType());
          }
        }

        if (CurMultiClass) {
          Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::");

          if (CurMultiClass->Rec.isTemplateArg(MCName)) {
            const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
            assert(RV && "Template arg doesn't exist??");

            if (RV->getType() != getType())
              PrintFatalError("type mismatch in cast");

            return VarInit::get(MCName, RV->getType());
          }
        }

792        if (Record *D = (CurRec->getRecords()).getDef(Name))  <-- if CurRec is NULL, it will be in trouble
          return DefInit::get(D);

        PrintFatalError(CurRec->getLoc(),
                        "Undefined reference:'" + Name + "'\n");
      }
    }
    break;
  }
  case HEAD: {
    if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
      if (LHSl->getSize() == 0) {
        assert(0 && "Empty list in car");
        return 0;
      }
      return LHSl->getElement(0);
    }
    break;
  }
  case TAIL: {
    if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
      if (LHSl->getSize() == 0) {
        assert(0 && "Empty list in cdr");
        return 0;
      }
      // Note the +1.  We can't just pass the result of getValues()
      // directly.
      ArrayRef<Init *>::iterator begin = LHSl->getValues().begin()+1;
      ArrayRef<Init *>::iterator end   = LHSl->getValues().end();
      ListInit *Result =
        ListInit::get(ArrayRef<Init *>(begin, end - begin),
                      LHSl->getType());
      return Result;
    }
    break;
  }
  case EMPTY: {
    if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
      if (LHSl->getSize() == 0) {
        return IntInit::get(1);
      } else {
        return IntInit::get(0);
      }
    }
    if (StringInit *LHSs = dyn_cast<StringInit>(LHS)) {
      if (LHSs->getValue().empty()) {
        return IntInit::get(1);
      } else {
        return IntInit::get(0);
      }
    }

    break;
  }
  }
  return const_cast<UnOpInit *>(this);
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140514/25715ac4/attachment.html>


More information about the llvm-dev mailing list