From e36a05fd7f7d008c4c1e75ebf46eac3072ef71b1 Mon Sep 17 00:00:00 2001 From: Robert Goulet Date: Tue, 11 Aug 2015 15:18:39 -0400 Subject: [PATCH] cmTarget: Detect and diagnose recursion in GetOutputInfo --- Source/cmTarget.cxx | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d3170e4ae..d2d4c671f 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -66,6 +66,8 @@ struct cmTarget::OutputInfo std::string OutDir; std::string ImpDir; std::string PdbDir; + bool empty() const + { return OutDir.empty() && ImpDir.empty() && PdbDir.empty(); } }; //---------------------------------------------------------------------------- @@ -2609,19 +2611,35 @@ cmTarget::OutputInfo const* cmTarget::GetOutputInfo( config_upper = cmSystemTools::UpperCase(config); } typedef cmTargetInternals::OutputInfoMapType OutputInfoMapType; - OutputInfoMapType::const_iterator i = + OutputInfoMapType::iterator i = this->Internal->OutputInfoMap.find(config_upper); if(i == this->Internal->OutputInfoMap.end()) { + // Add empty info in map to detect potential recursion. OutputInfo info; + OutputInfoMapType::value_type entry(config_upper, info); + i = this->Internal->OutputInfoMap.insert(entry).first; + + // Compute output directories. this->ComputeOutputDir(config, false, info.OutDir); this->ComputeOutputDir(config, true, info.ImpDir); if(!this->ComputePDBOutputDir("PDB", config, info.PdbDir)) { info.PdbDir = info.OutDir; } - OutputInfoMapType::value_type entry(config_upper, info); - i = this->Internal->OutputInfoMap.insert(entry).first; + + // Now update the previously-prepared map entry. + i->second = info; + } + else if(i->second.empty()) + { + // An empty map entry indicates we have been called recursively + // from the above block. + this->Makefile->GetCMakeInstance()->IssueMessage( + cmake::FATAL_ERROR, + "Target '" + this->GetName() + "' OUTPUT_DIRECTORY depends on itself.", + this->GetBacktrace()); + return 0; } return &i->second; }