From f1200648bd54882c353c35a4331ad8c56fb68a7d Mon Sep 17 00:00:00 2001 From: Philip Pfaffe Date: Mon, 24 Apr 2017 11:54:37 +0000 Subject: [PATCH] [RegionInfo] Fix dangling references created by moving RegionInfo objects Summary: Region objects capture the address of the creating RegionInfo instance. Because the RegionInfo class is movable, moving a RegionInfo object creates dangling references. This patch fixes these references by walking the Regions post-move, and updating references to the new parent. Reviewers: Meinersbur, grosser Reviewed By: Meinersbur, grosser Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D31719 llvm-svn: 301175 --- llvm/include/llvm/Analysis/RegionInfo.h | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/Analysis/RegionInfo.h b/llvm/include/llvm/Analysis/RegionInfo.h index caeb21db613e7..16ee07fa31771 100644 --- a/llvm/include/llvm/Analysis/RegionInfo.h +++ b/llvm/include/llvm/Analysis/RegionInfo.h @@ -708,10 +708,24 @@ class RegionInfoBase { /// The top level region. RegionT *TopLevelRegion; -private: /// Map every BB to the smallest region, that contains BB. BBtoRegionMap BBtoRegion; +protected: + /// \brief Update refences to a RegionInfoT held by the RegionT managed here + /// + /// This is a post-move helper. Regions hold references to the owning + /// RegionInfo object. After a move these need to be fixed. + template + void updateRegionTree(RegionInfoT &RI, TheRegionT *R) { + if (!R) + return; + R->RI = &RI; + for (auto &SubR : *R) + updateRegionTree(RI, SubR.get()); + } + +private: /// \brief Wipe this region tree's state without releasing any resources. /// /// This is essentially a post-move helper only. It leaves the object in an @@ -879,10 +893,12 @@ class RegionInfo : public RegionInfoBase> { ~RegionInfo() override; - RegionInfo(RegionInfo &&Arg) - : Base(std::move(static_cast(Arg))) {} + RegionInfo(RegionInfo &&Arg) : Base(std::move(static_cast(Arg))) { + updateRegionTree(*this, TopLevelRegion); + } RegionInfo &operator=(RegionInfo &&RHS) { Base::operator=(std::move(static_cast(RHS))); + updateRegionTree(*this, TopLevelRegion); return *this; }