[tablegen] - Eliminate memory leaks in TGParser.cpp
authorAnton Yartsev <anton.yartsev@gmail.com>
Fri, 8 Aug 2014 00:29:54 +0000 (00:29 +0000)
committerAnton Yartsev <anton.yartsev@gmail.com>
Fri, 8 Aug 2014 00:29:54 +0000 (00:29 +0000)
Ugly solution indicating that a refactoring is necessary to get the ownership under control.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215176 91177308-0d34-0410-b5e6-96231b3b80d8

lib/TableGen/TGParser.cpp

index 66c6b85d696ab69a23122802e9b23e6d2329eaab..9c061a8ae4cbc7c22f12ebfb55c5666184448fa0 100644 (file)
@@ -236,8 +236,10 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC,
 
     // Add all of the values in the superclass into the current def.
     for (unsigned i = 0, e = MCVals.size(); i != e; ++i)
-      if (AddValue(NewDef, SubMultiClass.RefRange.Start, MCVals[i]))
+      if (AddValue(NewDef, SubMultiClass.RefRange.Start, MCVals[i])) {
+        delete NewDef;
         return true;
+      }
 
     CurMC->DefPrototypes.push_back(NewDef);
   }
@@ -348,6 +350,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
     TypedInit *IVal = dyn_cast<TypedInit>(IterVals[i].IterValue);
     if (!IVal) {
       Error(Loc, "foreach iterator value is untyped");
+      delete IterRec;
       return true;
     }
 
@@ -356,6 +359,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
     if (SetValue(IterRec, Loc, IterVar->getName(),
                  std::vector<unsigned>(), IVal)) {
       Error(Loc, "when instantiating this def");
+      delete IterRec;
       return true;
     }
 
@@ -372,6 +376,7 @@ bool TGParser::ProcessForeachDefs(Record *CurRec, SMLoc Loc, IterSet &IterVals){
       IterRec->setName(GetNewAnonymousName());
     else {
       Error(Loc, "def already exists: " + IterRec->getNameInitAsString());
+      delete IterRec;
       return true;
     }
   }
@@ -1251,8 +1256,10 @@ Init *TGParser::ParseSimpleValue(Record *CurRec, RecTy *ItemType,
     SCRef.Rec = Class;
     SCRef.TemplateArgs = ValueList;
     // Add info about the subclass to NewRec.
-    if (AddSubClass(NewRec, SCRef))
+    if (AddSubClass(NewRec, SCRef)) {
+      delete NewRec;
       return nullptr;
+    }
     if (!CurMultiClass) {
       NewRec->resolveReferences();
       Records.addDef(NewRec);
@@ -2017,6 +2024,7 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
 
   // Parse ObjectName and make a record for it.
   Record *CurRec;
+  bool CurRecOwnershipTransferred = false;
   Init *Name = ParseObjectName(CurMultiClass);
   if (Name)
     CurRec = new Record(Name, DefLoc, Records);
@@ -2031,9 +2039,11 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
     if (Records.getDef(CurRec->getNameInitAsString())) {
       Error(DefLoc, "def '" + CurRec->getNameInitAsString()
             + "' already defined");
+      delete CurRec;
       return true;
     }
     Records.addDef(CurRec);
+    CurRecOwnershipTransferred = true;
 
     if (ParseObjectBody(CurRec))
       return true;
@@ -2043,8 +2053,10 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
     // before this object, instantiated prior to defs derived from this object,
     // and this available for indirect name resolution when defs derived from
     // this object are instantiated.
-    if (ParseObjectBody(CurRec))
+    if (ParseObjectBody(CurRec)) {
+      delete CurRec;
       return true;
+    }
 
     // Otherwise, a def inside a multiclass, add it to the multiclass.
     for (unsigned i = 0, e = CurMultiClass->DefPrototypes.size(); i != e; ++i)
@@ -2052,11 +2064,15 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
           == CurRec->getNameInit()) {
         Error(DefLoc, "def '" + CurRec->getNameInitAsString() +
               "' already defined in this multiclass!");
+        delete CurRec;
         return true;
       }
     CurMultiClass->DefPrototypes.push_back(CurRec);
-  } else if (ParseObjectBody(CurRec))
+    CurRecOwnershipTransferred = true;
+  } else if (ParseObjectBody(CurRec)) {
+    delete CurRec;
     return true;
+  }
 
   if (!CurMultiClass)  // Def's in multiclasses aren't really defs.
     // See Record::setName().  This resolve step will see any new name
@@ -2082,9 +2098,13 @@ bool TGParser::ParseDef(MultiClass *CurMultiClass) {
   if (ProcessForeachDefs(CurRec, DefLoc)) {
     Error(DefLoc,
           "Could not process loops for def" + CurRec->getNameInitAsString());
+    if (!CurRecOwnershipTransferred)
+      delete CurRec;
     return true;
   }
 
+  if (!CurRecOwnershipTransferred)
+    delete CurRec;
   return false;
 }
 
@@ -2398,6 +2418,7 @@ InstantiateMulticlassDef(MultiClass &MC,
     Error(DefmPrefixRange.Start, "Could not resolve "
           + CurRec->getNameInitAsString() + ":NAME to '"
           + DefmPrefix->getAsUnquotedString() + "'");
+    delete CurRec;
     return nullptr;
   }
 
@@ -2429,6 +2450,7 @@ InstantiateMulticlassDef(MultiClass &MC,
       Error(DefmPrefixRange.Start, "def '" + CurRec->getNameInitAsString() +
             "' already defined, instantiating defm with subdef '" + 
             DefProto->getNameInitAsString() + "'");
+      delete CurRec;
       return nullptr;
     }