mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-11 13:44:28 +00:00
[TableGen] Prevent DagInit from leaking its Args and ArgNames when they exceed the size of the SmallVector.
DagInits are allocated in a BumpPtrAllocator so they are never destructed. This means the destructor for the SmallVector never runs. To fix this we now allocate the vectors in the BumpPtrAllocator too using TrailingObjects. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304077 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8e1db259e8
commit
67886788e2
@ -1137,17 +1137,19 @@ public:
|
||||
/// to have at least one value then a (possibly empty) list of arguments. Each
|
||||
/// argument can have a name associated with it.
|
||||
///
|
||||
class DagInit : public TypedInit, public FoldingSetNode {
|
||||
class DagInit final : public TypedInit, public FoldingSetNode,
|
||||
public TrailingObjects<DagInit, Init *, StringInit *> {
|
||||
Init *Val;
|
||||
StringInit *ValName;
|
||||
SmallVector<Init*, 4> Args;
|
||||
SmallVector<StringInit*, 4> ArgNames;
|
||||
unsigned NumArgs;
|
||||
unsigned NumArgNames;
|
||||
|
||||
DagInit(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
|
||||
ArrayRef<StringInit *> NameRange)
|
||||
DagInit(Init *V, StringInit *VN, unsigned NumArgs, unsigned NumArgNames)
|
||||
: TypedInit(IK_DagInit, DagRecTy::get()), Val(V), ValName(VN),
|
||||
Args(ArgRange.begin(), ArgRange.end()),
|
||||
ArgNames(NameRange.begin(), NameRange.end()) {}
|
||||
NumArgs(NumArgs), NumArgNames(NumArgNames) {}
|
||||
|
||||
friend TrailingObjects;
|
||||
size_t numTrailingObjects(OverloadToken<Init *>) const { return NumArgs; }
|
||||
|
||||
public:
|
||||
DagInit(const DagInit &Other) = delete;
|
||||
@ -1173,20 +1175,24 @@ public:
|
||||
return ValName ? ValName->getValue() : StringRef();
|
||||
}
|
||||
|
||||
unsigned getNumArgs() const { return Args.size(); }
|
||||
unsigned getNumArgs() const { return NumArgs; }
|
||||
Init *getArg(unsigned Num) const {
|
||||
assert(Num < Args.size() && "Arg number out of range!");
|
||||
return Args[Num];
|
||||
assert(Num < NumArgs && "Arg number out of range!");
|
||||
return getTrailingObjects<Init *>()[Num];
|
||||
}
|
||||
StringInit *getArgName(unsigned Num) const {
|
||||
assert(Num < ArgNames.size() && "Arg number out of range!");
|
||||
return ArgNames[Num];
|
||||
assert(Num < NumArgNames && "Arg number out of range!");
|
||||
return getTrailingObjects<StringInit *>()[Num];
|
||||
}
|
||||
StringRef getArgNameStr(unsigned Num) const {
|
||||
StringInit *Init = getArgName(Num);
|
||||
return Init ? Init->getValue() : StringRef();
|
||||
}
|
||||
|
||||
ArrayRef<StringInit *> getArgNames() const {
|
||||
return makeArrayRef(getTrailingObjects<StringInit *>(), NumArgNames);
|
||||
}
|
||||
|
||||
Init *resolveReferences(Record &R, const RecordVal *RV) const override;
|
||||
|
||||
std::string getAsString() const override;
|
||||
@ -1194,20 +1200,20 @@ public:
|
||||
typedef SmallVectorImpl<Init*>::const_iterator const_arg_iterator;
|
||||
typedef SmallVectorImpl<StringInit*>::const_iterator const_name_iterator;
|
||||
|
||||
inline const_arg_iterator arg_begin() const { return Args.begin(); }
|
||||
inline const_arg_iterator arg_end () const { return Args.end(); }
|
||||
inline const_arg_iterator arg_begin() const { return getTrailingObjects<Init *>(); }
|
||||
inline const_arg_iterator arg_end () const { return arg_begin() + NumArgs; }
|
||||
inline iterator_range<const_arg_iterator> args() const {
|
||||
return llvm::make_range(arg_begin(), arg_end());
|
||||
}
|
||||
|
||||
inline size_t arg_size () const { return Args.size(); }
|
||||
inline bool arg_empty() const { return Args.empty(); }
|
||||
inline size_t arg_size () const { return NumArgs; }
|
||||
inline bool arg_empty() const { return NumArgs == 0; }
|
||||
|
||||
inline const_name_iterator name_begin() const { return ArgNames.begin(); }
|
||||
inline const_name_iterator name_end () const { return ArgNames.end(); }
|
||||
inline const_name_iterator name_begin() const { return getTrailingObjects<StringInit *>(); }
|
||||
inline const_name_iterator name_end () const { return name_begin() + NumArgNames; }
|
||||
|
||||
inline size_t name_size () const { return ArgNames.size(); }
|
||||
inline bool name_empty() const { return ArgNames.empty(); }
|
||||
inline size_t name_size () const { return NumArgNames; }
|
||||
inline bool name_empty() const { return NumArgNames == 0; }
|
||||
|
||||
Init *getBit(unsigned Bit) const override {
|
||||
llvm_unreachable("Illegal bit reference off dag");
|
||||
|
@ -1501,7 +1501,12 @@ DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
|
||||
if (DagInit *I = ThePool.FindNodeOrInsertPos(ID, IP))
|
||||
return I;
|
||||
|
||||
DagInit *I = new(Allocator) DagInit(V, VN, ArgRange, NameRange);
|
||||
void *Mem = Allocator.Allocate(totalSizeToAlloc<Init *, StringInit *>(ArgRange.size(), NameRange.size()), alignof(BitsInit));
|
||||
DagInit *I = new(Mem) DagInit(V, VN, ArgRange.size(), NameRange.size());
|
||||
std::uninitialized_copy(ArgRange.begin(), ArgRange.end(),
|
||||
I->getTrailingObjects<Init *>());
|
||||
std::uninitialized_copy(NameRange.begin(), NameRange.end(),
|
||||
I->getTrailingObjects<StringInit *>());
|
||||
ThePool.InsertNode(I, IP);
|
||||
return I;
|
||||
}
|
||||
@ -1521,7 +1526,7 @@ DagInit::get(Init *V, StringInit *VN,
|
||||
}
|
||||
|
||||
void DagInit::Profile(FoldingSetNodeID &ID) const {
|
||||
ProfileDagInit(ID, Val, ValName, Args, ArgNames);
|
||||
ProfileDagInit(ID, Val, ValName, makeArrayRef(getTrailingObjects<Init *>(), NumArgs), makeArrayRef(getTrailingObjects<StringInit *>(), NumArgNames));
|
||||
}
|
||||
|
||||
Init *DagInit::convertInitializerTo(RecTy *Ty) const {
|
||||
@ -1533,9 +1538,9 @@ Init *DagInit::convertInitializerTo(RecTy *Ty) const {
|
||||
|
||||
Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) const {
|
||||
SmallVector<Init*, 8> NewArgs;
|
||||
NewArgs.reserve(Args.size());
|
||||
NewArgs.reserve(arg_size());
|
||||
bool ArgsChanged = false;
|
||||
for (const Init *Arg : Args) {
|
||||
for (const Init *Arg : args()) {
|
||||
Init *NewArg = Arg->resolveReferences(R, RV);
|
||||
NewArgs.push_back(NewArg);
|
||||
ArgsChanged |= NewArg != Arg;
|
||||
@ -1543,7 +1548,7 @@ Init *DagInit::resolveReferences(Record &R, const RecordVal *RV) const {
|
||||
|
||||
Init *Op = Val->resolveReferences(R, RV);
|
||||
if (Op != Val || ArgsChanged)
|
||||
return DagInit::get(Op, ValName, NewArgs, ArgNames);
|
||||
return DagInit::get(Op, ValName, NewArgs, getArgNames());
|
||||
|
||||
return const_cast<DagInit *>(this);
|
||||
}
|
||||
@ -1552,12 +1557,12 @@ std::string DagInit::getAsString() const {
|
||||
std::string Result = "(" + Val->getAsString();
|
||||
if (ValName)
|
||||
Result += ":" + ValName->getAsUnquotedString();
|
||||
if (!Args.empty()) {
|
||||
Result += " " + Args[0]->getAsString();
|
||||
if (ArgNames[0]) Result += ":$" + ArgNames[0]->getAsUnquotedString();
|
||||
for (unsigned i = 1, e = Args.size(); i != e; ++i) {
|
||||
Result += ", " + Args[i]->getAsString();
|
||||
if (ArgNames[i]) Result += ":$" + ArgNames[i]->getAsUnquotedString();
|
||||
if (!arg_empty()) {
|
||||
Result += " " + getArg(0)->getAsString();
|
||||
if (getArgName(0)) Result += ":$" + getArgName(0)->getAsUnquotedString();
|
||||
for (unsigned i = 1, e = getNumArgs(); i != e; ++i) {
|
||||
Result += ", " + getArg(i)->getAsString();
|
||||
if (getArgName(i)) Result += ":$" + getArgName(i)->getAsUnquotedString();
|
||||
}
|
||||
}
|
||||
return Result + ")";
|
||||
|
Loading…
Reference in New Issue
Block a user