diff --git a/clang/lib/AST/ByteCode/InterpBlock.cpp b/clang/lib/AST/ByteCode/InterpBlock.cpp index ac6f01f3cdca1..24825ad2557ef 100644 --- a/clang/lib/AST/ByteCode/InterpBlock.cpp +++ b/clang/lib/AST/ByteCode/InterpBlock.cpp @@ -100,6 +100,19 @@ bool Block::hasPointer(const Pointer *P) const { } #endif +void Block::movePointersTo(Block *B) { + assert(B != this); + + while (Pointers) { + Pointer *P = Pointers; + + this->removePointer(P); + P->BS.Pointee = B; + B->addPointer(P); + } + assert(!this->hasPointers()); +} + DeadBlock::DeadBlock(DeadBlock *&Root, Block *Blk) : Root(Root), B(~0u, Blk->Desc, Blk->isExtern(), Blk->IsStatic, Blk->isWeak(), Blk->isDummy(), /*IsDead=*/true) { diff --git a/clang/lib/AST/ByteCode/InterpBlock.h b/clang/lib/AST/ByteCode/InterpBlock.h index 9b3dadca6cc14..73fdc8d85da11 100644 --- a/clang/lib/AST/ByteCode/InterpBlock.h +++ b/clang/lib/AST/ByteCode/InterpBlock.h @@ -92,6 +92,8 @@ class Block final { bool isInitialized() const { return IsInitialized; } /// The Evaluation ID this block was created in. unsigned getEvalID() const { return EvalID; } + /// Move all pointers from this block to \param B. + void movePointersTo(Block *B); /// Returns a pointer to the stored data. /// You are allowed to read Desc->getSize() bytes from this address. diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp index 75bfd9fd2d8ec..e653782f61fdf 100644 --- a/clang/lib/AST/ByteCode/Program.cpp +++ b/clang/lib/AST/ByteCode/Program.cpp @@ -226,11 +226,7 @@ UnsignedOrNone Program::createGlobal(const ValueDecl *VD, const Expr *Init) { Globals[PIdx] = NewGlobal; // All pointers pointing to the previous extern decl now point to the // new decl. - for (Pointer *Ptr = RedeclBlock->Pointers; Ptr; Ptr = Ptr->BS.Next) { - RedeclBlock->removePointer(Ptr); - Ptr->BS.Pointee = NewGlobal->block(); - NewGlobal->block()->addPointer(Ptr); - } + RedeclBlock->movePointersTo(NewGlobal->block()); } } PIdx = *Idx;