[IR] Delete llvm::Constants using the correct type.
In most cases, this doesn't have much impact: the destructors just call the base class destructor anyway. A few subclasses of ConstantExpr actually store non-trivial data, though. Make sure we clean up appropriately. This is sort of ugly, but I don't see a good alternative given the constraints. Issue found by asan buildbots running the testcase for D80330. Differential Revision: https://reviews.llvm.org/D82509
This commit is contained in:
@@ -43,6 +43,8 @@ protected:
|
||||
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;
|
||||
|
||||
@@ -899,6 +899,8 @@ protected:
|
||||
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
|
||||
|
||||
@@ -220,6 +220,6 @@ void BitcodeReaderValueList::resolveConstantForwardRefs() {
|
||||
|
||||
// Update all ValueHandles, they should be the only users at this point.
|
||||
Placeholder->replaceAllUsesWith(RealVal);
|
||||
Placeholder->deleteValue();
|
||||
delete cast<ConstantPlaceHolder>(Placeholder);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,7 +463,74 @@ void Constant::destroyConstant() {
|
||||
}
|
||||
|
||||
// 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<ConstantInt *>(C);
|
||||
break;
|
||||
case Constant::ConstantFPVal:
|
||||
delete static_cast<ConstantFP *>(C);
|
||||
break;
|
||||
case Constant::ConstantAggregateZeroVal:
|
||||
delete static_cast<ConstantAggregateZero *>(C);
|
||||
break;
|
||||
case Constant::ConstantArrayVal:
|
||||
delete static_cast<ConstantArray *>(C);
|
||||
break;
|
||||
case Constant::ConstantStructVal:
|
||||
delete static_cast<ConstantStruct *>(C);
|
||||
break;
|
||||
case Constant::ConstantVectorVal:
|
||||
delete static_cast<ConstantVector *>(C);
|
||||
break;
|
||||
case Constant::ConstantPointerNullVal:
|
||||
delete static_cast<ConstantPointerNull *>(C);
|
||||
break;
|
||||
case Constant::ConstantDataArrayVal:
|
||||
delete static_cast<ConstantDataArray *>(C);
|
||||
break;
|
||||
case Constant::ConstantDataVectorVal:
|
||||
delete static_cast<ConstantDataVector *>(C);
|
||||
break;
|
||||
case Constant::ConstantTokenNoneVal:
|
||||
delete static_cast<ConstantTokenNone *>(C);
|
||||
break;
|
||||
case Constant::BlockAddressVal:
|
||||
delete static_cast<BlockAddress *>(C);
|
||||
break;
|
||||
case Constant::UndefValueVal:
|
||||
delete static_cast<UndefValue *>(C);
|
||||
break;
|
||||
case Constant::ConstantExprVal:
|
||||
if (isa<UnaryConstantExpr>(C))
|
||||
delete static_cast<UnaryConstantExpr *>(C);
|
||||
else if (isa<BinaryConstantExpr>(C))
|
||||
delete static_cast<BinaryConstantExpr *>(C);
|
||||
else if (isa<SelectConstantExpr>(C))
|
||||
delete static_cast<SelectConstantExpr *>(C);
|
||||
else if (isa<ExtractElementConstantExpr>(C))
|
||||
delete static_cast<ExtractElementConstantExpr *>(C);
|
||||
else if (isa<InsertElementConstantExpr>(C))
|
||||
delete static_cast<InsertElementConstantExpr *>(C);
|
||||
else if (isa<ShuffleVectorConstantExpr>(C))
|
||||
delete static_cast<ShuffleVectorConstantExpr *>(C);
|
||||
else if (isa<ExtractValueConstantExpr>(C))
|
||||
delete static_cast<ExtractValueConstantExpr *>(C);
|
||||
else if (isa<InsertValueConstantExpr>(C))
|
||||
delete static_cast<InsertValueConstantExpr *>(C);
|
||||
else if (isa<GetElementPtrConstantExpr>(C))
|
||||
delete static_cast<GetElementPtrConstantExpr *>(C);
|
||||
else if (isa<CompareConstantExpr>(C))
|
||||
delete static_cast<CompareConstantExpr *>(C);
|
||||
else
|
||||
llvm_unreachable("Unexpected constant expr");
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unexpected constant");
|
||||
}
|
||||
}
|
||||
|
||||
static bool canTrapImpl(const Constant *C,
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace llvm {
|
||||
|
||||
/// 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 @@ public:
|
||||
|
||||
/// 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 @@ public:
|
||||
|
||||
/// 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 @@ public:
|
||||
/// 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<VectorType>(C1->getType())->getElementType(),
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
/// 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 @@ public:
|
||||
/// 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<int> Mask)
|
||||
: ConstantExpr(VectorType::get(
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
/// 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<unsigned> IdxList,
|
||||
Type *DestTy)
|
||||
@@ -204,7 +204,7 @@ public:
|
||||
/// 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<unsigned> IdxList, Type *DestTy)
|
||||
@@ -235,7 +235,7 @@ public:
|
||||
|
||||
/// 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 @@ public:
|
||||
// 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 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Free memory for a given constant. Assumes the constant has already been
|
||||
// removed from all relevant maps.
|
||||
void deleteConstant(Constant *C);
|
||||
|
||||
template <class ConstantClass> class ConstantUniqueMap {
|
||||
public:
|
||||
using ValType = typename ConstantInfo<ConstantClass>::ValType;
|
||||
@@ -660,7 +664,7 @@ public:
|
||||
|
||||
void freeConstants() {
|
||||
for (auto &I : Map)
|
||||
delete I; // Asserts that use_empty().
|
||||
deleteConstant(I);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -733,6 +737,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <> inline void ConstantUniqueMap<InlineAsm>::freeConstants() {
|
||||
for (auto &I : Map)
|
||||
delete I;
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_IR_CONSTANTSCONTEXT_H
|
||||
|
||||
@@ -111,6 +111,10 @@ void Value::deleteValue() {
|
||||
static_cast<DerivedUser *>(this)->DeleteValue( \
|
||||
static_cast<DerivedUser *>(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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user