Răsfoiți Sursa

BUG: cmTarget instances should not be copied. Removed pass-by-value arguments from cmLocalVisualStudio7Generator::WriteGroup and cmLocalVisualStudio6Generator::WriteGroup. Updated cmTarget to make this easier to find.

Brad King 17 ani în urmă
părinte
comite
6066e92ba2

+ 1 - 1
Source/cmLocalVisualStudio6Generator.cxx

@@ -351,7 +351,7 @@ void cmLocalVisualStudio6Generator::WriteDSPFile(std::ostream& fout,
 }
 
 void cmLocalVisualStudio6Generator
-::WriteGroup(const cmSourceGroup *sg, cmTarget target, 
+::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
              std::ostream &fout, const char *libName)
 {
   const std::vector<const cmSourceFile *> &sourceFiles = 

+ 1 - 1
Source/cmLocalVisualStudio6Generator.h

@@ -91,7 +91,7 @@ private:
   void AddUtilityCommandHack(cmTarget& target, int count,
                              std::vector<std::string>& depends,
                              const cmCustomCommand& origCommand);
-  void WriteGroup(const cmSourceGroup *sg, cmTarget target,
+  void WriteGroup(const cmSourceGroup *sg, cmTarget& target,
                   std::ostream &fout, const char *libName);
   std::string CreateTargetRules(cmTarget &target, 
                                 const char* configName, 

+ 1 - 1
Source/cmLocalVisualStudio7Generator.cxx

@@ -1179,7 +1179,7 @@ cmLocalVisualStudio7GeneratorFCInfo
 }
 
 void cmLocalVisualStudio7Generator
-::WriteGroup(const cmSourceGroup *sg, cmTarget target, 
+::WriteGroup(const cmSourceGroup *sg, cmTarget& target,
              std::ostream &fout, const char *libName, 
              std::vector<std::string> *configs)
 {

+ 1 - 1
Source/cmLocalVisualStudio7Generator.h

@@ -114,7 +114,7 @@ private:
   void WriteTargetVersionAttribute(std::ostream& fout, cmTarget& target);
 
   void WriteGroup(const cmSourceGroup *sg, 
-                  cmTarget target, std::ostream &fout, 
+                  cmTarget& target, std::ostream &fout,
                   const char *libName, std::vector<std::string> *configs);
   virtual std::string GetTargetDirectory(cmTarget const&) const;
 

+ 24 - 11
Source/cmTarget.cxx

@@ -25,6 +25,7 @@
 #include <set>
 #include <queue>
 #include <stdlib.h> // required for atof
+#include <assert.h>
 const char* cmTarget::TargetTypeNames[] = {
   "EXECUTABLE", "STATIC_LIBRARY",
   "SHARED_LIBRARY", "MODULE_LIBRARY", "UTILITY", "GLOBAL_TARGET",
@@ -41,17 +42,6 @@ cmTarget::cmTarget()
   this->IsImportedTarget = false;
 }
 
-//----------------------------------------------------------------------------
-cmTarget::~cmTarget()
-{
-  for(std::map<cmStdString, cmComputeLinkInformation*>::iterator
-        i = this->LinkInformation.begin();
-      i != this->LinkInformation.end(); ++i)
-    {
-    delete i->second;
-    }
-}
-
 //----------------------------------------------------------------------------
 void cmTarget::DefineProperties(cmake *cm)
 {
@@ -3075,3 +3065,26 @@ cmTarget::GetLinkInformation(const char* config)
     }
   return i->second;
 }
+
+//----------------------------------------------------------------------------
+cmTargetLinkInformationMap
+::cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r): derived()
+{
+  // Ideally cmTarget instances should never be copied.  However until
+  // we can make a sweep to remove that, this copy constructor avoids
+  // allowing the resources (LinkInformation) from getting copied.  In
+  // the worst case this will lead to extra cmComputeLinkInformation
+  // instances.  We also enforce in debug mode that the map be emptied
+  // when copied.
+  static_cast<void>(r);
+  assert(r.empty());
+}
+
+//----------------------------------------------------------------------------
+cmTargetLinkInformationMap::~cmTargetLinkInformationMap()
+{
+  for(derived::iterator i = this->begin(); i != this->end(); ++i)
+    {
+    delete i->second;
+    }
+}

+ 10 - 2
Source/cmTarget.h

@@ -26,6 +26,15 @@ class cmSourceFile;
 class cmGlobalGenerator;
 class cmComputeLinkInformation;
 
+struct cmTargetLinkInformationMap:
+  public std::map<cmStdString, cmComputeLinkInformation*>
+{
+  typedef std::map<cmStdString, cmComputeLinkInformation*> derived;
+  cmTargetLinkInformationMap() {}
+  cmTargetLinkInformationMap(cmTargetLinkInformationMap const& r);
+  ~cmTargetLinkInformationMap();
+};
+
 /** \class cmTarget
  * \brief Represent a library or executable target loaded from a makefile.
  *
@@ -36,7 +45,6 @@ class cmTarget
 {
 public:
   cmTarget();
-  ~cmTarget();
   enum TargetType { EXECUTABLE, STATIC_LIBRARY,
                     SHARED_LIBRARY, MODULE_LIBRARY, UTILITY, GLOBAL_TARGET,
                     INSTALL_FILES, INSTALL_PROGRAMS, INSTALL_DIRECTORY};
@@ -466,7 +474,7 @@ private:
   ImportInfo const* GetImportInfo(const char* config);
   void ComputeImportInfo(std::string const& desired_config, ImportInfo& info);
 
-  std::map<cmStdString, cmComputeLinkInformation*> LinkInformation;
+  cmTargetLinkInformationMap LinkInformation;
 
   // The cmMakefile instance that owns this target.  This should
   // always be set.