forked from OSchip/llvm-project
[Clang] Fix memory leak due to TemplateArgumentListInfo used in AST node.
It looks like the leak is rooted at the allocation here:1a155ee7de/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (L3857)
The VarTemplateSpecializationDecl is allocated using placement new which uses the AST structure for ownership:1a155ee7de/clang/lib/AST/DeclBase.cpp (L99)
The problem is the TemplateArgumentListInfo inside1a155ee7de/clang/include/clang/AST/DeclTemplate.h (L2721)
This object contains a vector which does not use placement new:1a155ee7de/clang/include/clang/AST/TemplateBase.h (L564)
Apparently ASTTemplateArgumentListInfo should be used instead1a155ee7de/clang/include/clang/AST/TemplateBase.h (L575)
https://reviews.llvm.org/D125802#3551305 Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D126944
This commit is contained in:
parent
0392d425bb
commit
c7689fd552
|
@ -53,8 +53,10 @@ getTemplateSpecializationArgLocs(const NamedDecl &ND) {
|
||||||
llvm::dyn_cast<VarTemplatePartialSpecializationDecl>(&ND)) {
|
llvm::dyn_cast<VarTemplatePartialSpecializationDecl>(&ND)) {
|
||||||
if (auto *Args = Var->getTemplateArgsAsWritten())
|
if (auto *Args = Var->getTemplateArgsAsWritten())
|
||||||
return Args->arguments();
|
return Args->arguments();
|
||||||
} else if (auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND))
|
} else if (auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND)) {
|
||||||
return Var->getTemplateArgsInfo().arguments();
|
if (auto *Args = Var->getTemplateArgsInfo())
|
||||||
|
return Args->arguments();
|
||||||
|
}
|
||||||
// We return None for ClassTemplateSpecializationDecls because it does not
|
// We return None for ClassTemplateSpecializationDecls because it does not
|
||||||
// contain TemplateArgumentLoc information.
|
// contain TemplateArgumentLoc information.
|
||||||
return llvm::None;
|
return llvm::None;
|
||||||
|
|
|
@ -168,6 +168,8 @@ Bug Fixes
|
||||||
`Issue 55562 <https://github.com/llvm/llvm-project/issues/55562>`_.
|
`Issue 55562 <https://github.com/llvm/llvm-project/issues/55562>`_.
|
||||||
- Clang will allow calling a ``consteval`` function in a default argument. This
|
- Clang will allow calling a ``consteval`` function in a default argument. This
|
||||||
fixes `Issue 48230 <https://github.com/llvm/llvm-project/issues/48230>`_.
|
fixes `Issue 48230 <https://github.com/llvm/llvm-project/issues/48230>`_.
|
||||||
|
- Fixed memory leak due to ``VarTemplateSpecializationDecl`` using
|
||||||
|
``TemplateArgumentListInfo`` instead of ``ASTTemplateArgumentListInfo``.
|
||||||
|
|
||||||
Improvements to Clang's diagnostics
|
Improvements to Clang's diagnostics
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -2718,7 +2718,7 @@ class VarTemplateSpecializationDecl : public VarDecl,
|
||||||
|
|
||||||
/// The template arguments used to describe this specialization.
|
/// The template arguments used to describe this specialization.
|
||||||
const TemplateArgumentList *TemplateArgs;
|
const TemplateArgumentList *TemplateArgs;
|
||||||
TemplateArgumentListInfo TemplateArgsInfo;
|
const ASTTemplateArgumentListInfo *TemplateArgsInfo = nullptr;
|
||||||
|
|
||||||
/// The point where this template was instantiated (if any).
|
/// The point where this template was instantiated (if any).
|
||||||
SourceLocation PointOfInstantiation;
|
SourceLocation PointOfInstantiation;
|
||||||
|
@ -2773,8 +2773,9 @@ public:
|
||||||
|
|
||||||
// TODO: Always set this when creating the new specialization?
|
// TODO: Always set this when creating the new specialization?
|
||||||
void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
|
void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
|
||||||
|
void setTemplateArgsInfo(const ASTTemplateArgumentListInfo *ArgsInfo);
|
||||||
|
|
||||||
const TemplateArgumentListInfo &getTemplateArgsInfo() const {
|
const ASTTemplateArgumentListInfo *getTemplateArgsInfo() const {
|
||||||
return TemplateArgsInfo;
|
return TemplateArgsInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -618,6 +618,9 @@ private:
|
||||||
|
|
||||||
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
|
ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List);
|
||||||
|
|
||||||
|
// FIXME: Is it ever necessary to copy to another context?
|
||||||
|
ASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *List);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// The source location of the left angle bracket ('<').
|
/// The source location of the left angle bracket ('<').
|
||||||
SourceLocation LAngleLoc;
|
SourceLocation LAngleLoc;
|
||||||
|
@ -647,6 +650,10 @@ public:
|
||||||
|
|
||||||
static const ASTTemplateArgumentListInfo *
|
static const ASTTemplateArgumentListInfo *
|
||||||
Create(const ASTContext &C, const TemplateArgumentListInfo &List);
|
Create(const ASTContext &C, const TemplateArgumentListInfo &List);
|
||||||
|
|
||||||
|
// FIXME: Is it ever necessary to copy to another context?
|
||||||
|
static const ASTTemplateArgumentListInfo *
|
||||||
|
Create(const ASTContext &C, const ASTTemplateArgumentListInfo *List);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents an explicit template argument list in C++, e.g.,
|
/// Represents an explicit template argument list in C++, e.g.,
|
||||||
|
|
|
@ -6018,9 +6018,10 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
|
||||||
return TInfoOrErr.takeError();
|
return TInfoOrErr.takeError();
|
||||||
|
|
||||||
TemplateArgumentListInfo ToTAInfo;
|
TemplateArgumentListInfo ToTAInfo;
|
||||||
if (Error Err = ImportTemplateArgumentListInfo(
|
if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) {
|
||||||
D->getTemplateArgsInfo(), ToTAInfo))
|
if (Error Err = ImportTemplateArgumentListInfo(*Args, ToTAInfo))
|
||||||
return std::move(Err);
|
return std::move(Err);
|
||||||
|
}
|
||||||
|
|
||||||
using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
|
using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
|
||||||
// Create a new specialization.
|
// Create a new specialization.
|
||||||
|
|
|
@ -1335,10 +1335,14 @@ VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
|
||||||
|
|
||||||
void VarTemplateSpecializationDecl::setTemplateArgsInfo(
|
void VarTemplateSpecializationDecl::setTemplateArgsInfo(
|
||||||
const TemplateArgumentListInfo &ArgsInfo) {
|
const TemplateArgumentListInfo &ArgsInfo) {
|
||||||
TemplateArgsInfo.setLAngleLoc(ArgsInfo.getLAngleLoc());
|
TemplateArgsInfo =
|
||||||
TemplateArgsInfo.setRAngleLoc(ArgsInfo.getRAngleLoc());
|
ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
|
||||||
for (const TemplateArgumentLoc &Loc : ArgsInfo.arguments())
|
}
|
||||||
TemplateArgsInfo.addArgument(Loc);
|
|
||||||
|
void VarTemplateSpecializationDecl::setTemplateArgsInfo(
|
||||||
|
const ASTTemplateArgumentListInfo *ArgsInfo) {
|
||||||
|
TemplateArgsInfo =
|
||||||
|
ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -617,6 +617,17 @@ ASTTemplateArgumentListInfo::Create(const ASTContext &C,
|
||||||
return new (Mem) ASTTemplateArgumentListInfo(List);
|
return new (Mem) ASTTemplateArgumentListInfo(List);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ASTTemplateArgumentListInfo *
|
||||||
|
ASTTemplateArgumentListInfo::Create(const ASTContext &C,
|
||||||
|
const ASTTemplateArgumentListInfo *List) {
|
||||||
|
if (!List)
|
||||||
|
return nullptr;
|
||||||
|
std::size_t size =
|
||||||
|
totalSizeToAlloc<TemplateArgumentLoc>(List->getNumTemplateArgs());
|
||||||
|
void *Mem = C.Allocate(size, alignof(ASTTemplateArgumentListInfo));
|
||||||
|
return new (Mem) ASTTemplateArgumentListInfo(List);
|
||||||
|
}
|
||||||
|
|
||||||
ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
|
ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
|
||||||
const TemplateArgumentListInfo &Info) {
|
const TemplateArgumentListInfo &Info) {
|
||||||
LAngleLoc = Info.getLAngleLoc();
|
LAngleLoc = Info.getLAngleLoc();
|
||||||
|
@ -628,6 +639,17 @@ ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
|
||||||
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
|
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASTTemplateArgumentListInfo::ASTTemplateArgumentListInfo(
|
||||||
|
const ASTTemplateArgumentListInfo *Info) {
|
||||||
|
LAngleLoc = Info->getLAngleLoc();
|
||||||
|
RAngleLoc = Info->getRAngleLoc();
|
||||||
|
NumTemplateArgs = Info->getNumTemplateArgs();
|
||||||
|
|
||||||
|
TemplateArgumentLoc *ArgBuffer = getTrailingObjects<TemplateArgumentLoc>();
|
||||||
|
for (unsigned i = 0; i != NumTemplateArgs; ++i)
|
||||||
|
new (&ArgBuffer[i]) TemplateArgumentLoc((*Info)[i]);
|
||||||
|
}
|
||||||
|
|
||||||
void ASTTemplateKWAndArgsInfo::initializeFrom(
|
void ASTTemplateKWAndArgsInfo::initializeFrom(
|
||||||
SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
|
SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info,
|
||||||
TemplateArgumentLoc *OutArgArray) {
|
TemplateArgumentLoc *OutArgArray) {
|
||||||
|
|
|
@ -3801,13 +3801,15 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Substitute the current template arguments.
|
// Substitute the current template arguments.
|
||||||
const TemplateArgumentListInfo &TemplateArgsInfo = D->getTemplateArgsInfo();
|
if (const ASTTemplateArgumentListInfo *TemplateArgsInfo =
|
||||||
VarTemplateArgsInfo.setLAngleLoc(TemplateArgsInfo.getLAngleLoc());
|
D->getTemplateArgsInfo()) {
|
||||||
VarTemplateArgsInfo.setRAngleLoc(TemplateArgsInfo.getRAngleLoc());
|
VarTemplateArgsInfo.setLAngleLoc(TemplateArgsInfo->getLAngleLoc());
|
||||||
|
VarTemplateArgsInfo.setRAngleLoc(TemplateArgsInfo->getRAngleLoc());
|
||||||
|
|
||||||
if (SemaRef.SubstTemplateArguments(TemplateArgsInfo.arguments(), TemplateArgs,
|
if (SemaRef.SubstTemplateArguments(TemplateArgsInfo->arguments(),
|
||||||
VarTemplateArgsInfo))
|
TemplateArgs, VarTemplateArgsInfo))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Check that the template argument list is well-formed for this template.
|
// Check that the template argument list is well-formed for this template.
|
||||||
SmallVector<TemplateArgument, 4> Converted;
|
SmallVector<TemplateArgument, 4> Converted;
|
||||||
|
@ -5554,8 +5556,18 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
|
||||||
// declaration of the definition.
|
// declaration of the definition.
|
||||||
TemplateDeclInstantiator Instantiator(*this, Var->getDeclContext(),
|
TemplateDeclInstantiator Instantiator(*this, Var->getDeclContext(),
|
||||||
TemplateArgs);
|
TemplateArgs);
|
||||||
|
|
||||||
|
TemplateArgumentListInfo TemplateArgInfo;
|
||||||
|
if (const ASTTemplateArgumentListInfo *ArgInfo =
|
||||||
|
VarSpec->getTemplateArgsInfo()) {
|
||||||
|
TemplateArgInfo.setLAngleLoc(ArgInfo->getLAngleLoc());
|
||||||
|
TemplateArgInfo.setRAngleLoc(ArgInfo->getRAngleLoc());
|
||||||
|
for (const TemplateArgumentLoc &Arg : ArgInfo->arguments())
|
||||||
|
TemplateArgInfo.addArgument(Arg);
|
||||||
|
}
|
||||||
|
|
||||||
Var = cast_or_null<VarDecl>(Instantiator.VisitVarTemplateSpecializationDecl(
|
Var = cast_or_null<VarDecl>(Instantiator.VisitVarTemplateSpecializationDecl(
|
||||||
VarSpec->getSpecializedTemplate(), Def, VarSpec->getTemplateArgsInfo(),
|
VarSpec->getSpecializedTemplate(), Def, TemplateArgInfo,
|
||||||
VarSpec->getTemplateArgs().asArray(), VarSpec));
|
VarSpec->getTemplateArgs().asArray(), VarSpec));
|
||||||
if (Var) {
|
if (Var) {
|
||||||
llvm::PointerUnion<VarTemplateDecl *,
|
llvm::PointerUnion<VarTemplateDecl *,
|
||||||
|
|
Loading…
Reference in New Issue