diff --git a/llvm/include/llvm/IR/Constant.h b/llvm/include/llvm/IR/Constant.h --- a/llvm/include/llvm/IR/Constant.h +++ b/llvm/include/llvm/IR/Constant.h @@ -43,6 +43,8 @@ Constant(Type *ty, ValueTy vty, Use *Ops, unsigned NumOps) : User(ty, vty, Ops, NumOps) {} + ~Constant() = default; + public: void operator=(const Constant &) = delete; Constant(const Constant &) = delete; diff --git a/llvm/include/llvm/IR/Constants.h b/llvm/include/llvm/IR/Constants.h --- a/llvm/include/llvm/IR/Constants.h +++ b/llvm/include/llvm/IR/Constants.h @@ -899,6 +899,8 @@ setValueSubclassData(Opcode); } + ~ConstantExpr() = default; + public: // Static methods to construct a ConstantExpr of different kinds. Note that // these methods may return a object that is not an instance of the diff --git a/llvm/lib/Bitcode/Reader/ValueList.cpp b/llvm/lib/Bitcode/Reader/ValueList.cpp --- a/llvm/lib/Bitcode/Reader/ValueList.cpp +++ b/llvm/lib/Bitcode/Reader/ValueList.cpp @@ -220,6 +220,6 @@ // Update all ValueHandles, they should be the only users at this point. Placeholder->replaceAllUsesWith(RealVal); - Placeholder->deleteValue(); + delete cast(Placeholder); } } diff --git a/llvm/lib/IR/Constants.cpp b/llvm/lib/IR/Constants.cpp --- a/llvm/lib/IR/Constants.cpp +++ b/llvm/lib/IR/Constants.cpp @@ -463,7 +463,74 @@ } // Value has no outstanding references it is safe to delete it now... - delete this; + deleteConstant(this); +} + +void llvm::deleteConstant(Constant *C) { + switch (C->getValueID()) { + case Constant::ConstantIntVal: + delete static_cast(C); + break; + case Constant::ConstantFPVal: + delete static_cast(C); + break; + case Constant::ConstantAggregateZeroVal: + delete static_cast(C); + break; + case Constant::ConstantArrayVal: + delete static_cast(C); + break; + case Constant::ConstantStructVal: + delete static_cast(C); + break; + case Constant::ConstantVectorVal: + delete static_cast(C); + break; + case Constant::ConstantPointerNullVal: + delete static_cast(C); + break; + case Constant::ConstantDataArrayVal: + delete static_cast(C); + break; + case Constant::ConstantDataVectorVal: + delete static_cast(C); + break; + case Constant::ConstantTokenNoneVal: + delete static_cast(C); + break; + case Constant::BlockAddressVal: + delete static_cast(C); + break; + case Constant::UndefValueVal: + delete static_cast(C); + break; + case Constant::ConstantExprVal: + if (isa(C)) + delete static_cast(C); + else if (isa(C)) + delete static_cast(C); + else if (isa(C)) + delete static_cast(C); + else if (isa(C)) + delete static_cast(C); + else if (isa(C)) + delete static_cast(C); + else if (isa(C)) + delete static_cast(C); + else if (isa(C)) + delete static_cast(C); + else if (isa(C)) + delete static_cast(C); + else if (isa(C)) + delete static_cast(C); + else if (isa(C)) + delete static_cast(C); + else + llvm_unreachable("Unexpected constant expr"); + break; + default: + llvm_unreachable("Unexpected constant"); + } } static bool canTrapImpl(const Constant *C, diff --git a/llvm/lib/IR/ConstantsContext.h b/llvm/lib/IR/ConstantsContext.h --- a/llvm/lib/IR/ConstantsContext.h +++ b/llvm/lib/IR/ConstantsContext.h @@ -43,7 +43,7 @@ /// UnaryConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement unary constant exprs. -class UnaryConstantExpr : public ConstantExpr { +class UnaryConstantExpr final : public ConstantExpr { public: UnaryConstantExpr(unsigned Opcode, Constant *C, Type *Ty) : ConstantExpr(Ty, Opcode, &Op<0>(), 1) { @@ -60,7 +60,7 @@ /// BinaryConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement binary constant exprs. -class BinaryConstantExpr : public ConstantExpr { +class BinaryConstantExpr final : public ConstantExpr { public: BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags) @@ -81,7 +81,7 @@ /// SelectConstantExpr - This class is private to Constants.cpp, and is used /// behind the scenes to implement select constant exprs. -class SelectConstantExpr : public ConstantExpr { +class SelectConstantExpr final : public ConstantExpr { public: SelectConstantExpr(Constant *C1, Constant *C2, Constant *C3) : ConstantExpr(C2->getType(), Instruction::Select, &Op<0>(), 3) { @@ -102,7 +102,7 @@ /// ExtractElementConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// extractelement constant exprs. -class ExtractElementConstantExpr : public ConstantExpr { +class ExtractElementConstantExpr final : public ConstantExpr { public: ExtractElementConstantExpr(Constant *C1, Constant *C2) : ConstantExpr(cast(C1->getType())->getElementType(), @@ -123,7 +123,7 @@ /// InsertElementConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// insertelement constant exprs. -class InsertElementConstantExpr : public ConstantExpr { +class InsertElementConstantExpr final : public ConstantExpr { public: InsertElementConstantExpr(Constant *C1, Constant *C2, Constant *C3) : ConstantExpr(C1->getType(), Instruction::InsertElement, @@ -145,7 +145,7 @@ /// ShuffleVectorConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// shufflevector constant exprs. -class ShuffleVectorConstantExpr : public ConstantExpr { +class ShuffleVectorConstantExpr final : public ConstantExpr { public: ShuffleVectorConstantExpr(Constant *C1, Constant *C2, ArrayRef Mask) : ConstantExpr(VectorType::get( @@ -173,7 +173,7 @@ /// ExtractValueConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// extractvalue constant exprs. -class ExtractValueConstantExpr : public ConstantExpr { +class ExtractValueConstantExpr final : public ConstantExpr { public: ExtractValueConstantExpr(Constant *Agg, ArrayRef IdxList, Type *DestTy) @@ -204,7 +204,7 @@ /// InsertValueConstantExpr - This class is private to /// Constants.cpp, and is used behind the scenes to implement /// insertvalue constant exprs. -class InsertValueConstantExpr : public ConstantExpr { +class InsertValueConstantExpr final : public ConstantExpr { public: InsertValueConstantExpr(Constant *Agg, Constant *Val, ArrayRef IdxList, Type *DestTy) @@ -235,7 +235,7 @@ /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is /// used behind the scenes to implement getelementpr constant exprs. -class GetElementPtrConstantExpr : public ConstantExpr { +class GetElementPtrConstantExpr final : public ConstantExpr { Type *SrcElementTy; Type *ResElementTy; @@ -269,7 +269,7 @@ // CompareConstantExpr - This class is private to Constants.cpp, and is used // behind the scenes to implement ICmp and FCmp constant expressions. This is // needed in order to store the predicate value for these instructions. -class CompareConstantExpr : public ConstantExpr { +class CompareConstantExpr final : public ConstantExpr { public: unsigned short predicate; CompareConstantExpr(Type *ty, Instruction::OtherOps opc, @@ -597,6 +597,10 @@ } }; +// Free memory for a given constant. Assumes the constant has already been +// removed from all relevant maps. +void deleteConstant(Constant *C); + template class ConstantUniqueMap { public: using ValType = typename ConstantInfo::ValType; @@ -660,7 +664,7 @@ void freeConstants() { for (auto &I : Map) - delete I; // Asserts that use_empty(). + deleteConstant(I); } private: @@ -733,6 +737,11 @@ } }; +template <> inline void ConstantUniqueMap::freeConstants() { + for (auto &I : Map) + delete I; +} + } // end namespace llvm #endif // LLVM_LIB_IR_CONSTANTSCONTEXT_H diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -111,6 +111,10 @@ static_cast(this)->DeleteValue( \ static_cast(this)); \ break; +#define HANDLE_CONSTANT(Name) \ + case Value::Name##Val: \ + llvm_unreachable("constants should be destroyed with destroyConstant"); \ + break; #define HANDLE_INSTRUCTION(Name) /* nothing */ #include "llvm/IR/Value.def"