Skip to content

Commit e9a2443

Browse files
committed
Don't use TemplateArgumentListInfo inside AST nodes because it may leak.
Use ASTTemplateArgumentListInfo instead. llvm-svn: 140331
1 parent de6aa08 commit e9a2443

File tree

12 files changed

+148
-113
lines changed

12 files changed

+148
-113
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class StringLiteral;
3333
class NestedNameSpecifier;
3434
class TemplateParameterList;
3535
class TemplateArgumentList;
36+
struct ASTTemplateArgumentListInfo;
3637
class MemberSpecializationInfo;
3738
class FunctionTemplateSpecializationInfo;
3839
class DependentFunctionTemplateSpecializationInfo;
@@ -1918,7 +1919,7 @@ class FunctionDecl : public DeclaratorDecl, public DeclContext,
19181919
/// or if it had no explicit template argument list, returns NULL.
19191920
/// Note that it an explicit template argument list may be written empty,
19201921
/// e.g., template<> void foo<>(char* s);
1921-
const TemplateArgumentListInfo*
1922+
const ASTTemplateArgumentListInfo*
19221923
getTemplateSpecializationArgsAsWritten() const;
19231924

19241925
/// \brief Specify that this function declaration is actually a function

clang/include/clang/AST/DeclTemplate.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
264264
FunctionTemplateDecl *Template,
265265
TemplateSpecializationKind TSK,
266266
const TemplateArgumentList *TemplateArgs,
267-
const TemplateArgumentListInfo *TemplateArgsAsWritten,
267+
const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
268268
SourceLocation POI)
269269
: Function(FD),
270270
Template(Template, TSK - 1),
@@ -278,12 +278,7 @@ class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
278278
TemplateSpecializationKind TSK,
279279
const TemplateArgumentList *TemplateArgs,
280280
const TemplateArgumentListInfo *TemplateArgsAsWritten,
281-
SourceLocation POI) {
282-
return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
283-
TemplateArgs,
284-
TemplateArgsAsWritten,
285-
POI);
286-
}
281+
SourceLocation POI);
287282

288283
/// \brief The function template specialization that this structure
289284
/// describes.
@@ -300,7 +295,7 @@ class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
300295
const TemplateArgumentList *TemplateArguments;
301296

302297
/// \brief The template arguments as written in the sources, if provided.
303-
const TemplateArgumentListInfo *TemplateArgumentsAsWritten;
298+
const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
304299

305300
/// \brief The point at which this function template specialization was
306301
/// first instantiated.

clang/include/clang/AST/Expr.h

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "clang/AST/DeclAccessPair.h"
2121
#include "clang/AST/OperationKinds.h"
2222
#include "clang/AST/ASTVector.h"
23+
#include "clang/AST/TemplateBase.h"
2324
#include "clang/AST/UsuallyTinyPtrVector.h"
2425
#include "clang/Basic/TypeTraits.h"
2526
#include "llvm/ADT/APSInt.h"
@@ -41,8 +42,6 @@ namespace clang {
4142
class CXXOperatorCallExpr;
4243
class CXXMemberCallExpr;
4344
class ObjCPropertyRefExpr;
44-
class TemplateArgumentLoc;
45-
class TemplateArgumentListInfo;
4645
class OpaqueValueExpr;
4746

4847
/// \brief A simple array of base specifiers.
@@ -688,41 +687,6 @@ class OpaqueValueExpr : public Expr {
688687
static bool classof(const OpaqueValueExpr *) { return true; }
689688
};
690689

691-
/// \brief Represents an explicit template argument list in C++, e.g.,
692-
/// the "<int>" in "sort<int>".
693-
/// This is safe to be used inside an AST node, in contrast with
694-
/// TemplateArgumentListInfo.
695-
struct ASTTemplateArgumentListInfo {
696-
/// \brief The source location of the left angle bracket ('<');
697-
SourceLocation LAngleLoc;
698-
699-
/// \brief The source location of the right angle bracket ('>');
700-
SourceLocation RAngleLoc;
701-
702-
/// \brief The number of template arguments in TemplateArgs.
703-
/// The actual template arguments (if any) are stored after the
704-
/// ExplicitTemplateArgumentList structure.
705-
unsigned NumTemplateArgs;
706-
707-
/// \brief Retrieve the template arguments
708-
TemplateArgumentLoc *getTemplateArgs() {
709-
return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
710-
}
711-
712-
/// \brief Retrieve the template arguments
713-
const TemplateArgumentLoc *getTemplateArgs() const {
714-
return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
715-
}
716-
717-
void initializeFrom(const TemplateArgumentListInfo &List);
718-
void initializeFrom(const TemplateArgumentListInfo &List,
719-
bool &Dependent, bool &InstantiationDependent,
720-
bool &ContainsUnexpandedParameterPack);
721-
void copyInto(TemplateArgumentListInfo &List) const;
722-
static std::size_t sizeFor(unsigned NumTemplateArgs);
723-
static std::size_t sizeFor(const TemplateArgumentListInfo &List);
724-
};
725-
726690
/// \brief A reference to a declared variable, function, enum, etc.
727691
/// [C99 6.5.1p2]
728692
///

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,10 +1552,10 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
15521552
FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
15531553
// A specialization might not have explicit template arguments if it has
15541554
// a templated return type and concrete arguments.
1555-
if (const TemplateArgumentListInfo *TALI =
1555+
if (const ASTTemplateArgumentListInfo *TALI =
15561556
FTSI->TemplateArgumentsAsWritten) {
1557-
TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getArgumentArray(),
1558-
TALI->size()));
1557+
TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
1558+
TALI->NumTemplateArgs));
15591559
}
15601560
}
15611561
}

clang/include/clang/AST/TemplateBase.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,10 @@ class TemplateArgumentListInfo {
518518
SourceLocation LAngleLoc;
519519
SourceLocation RAngleLoc;
520520

521+
// This can leak if used in an AST node, use ASTTemplateArgumentListInfo
522+
// instead.
523+
void* operator new(size_t bytes, ASTContext& C);
524+
521525
public:
522526
TemplateArgumentListInfo() {}
523527

@@ -546,6 +550,48 @@ class TemplateArgumentListInfo {
546550
}
547551
};
548552

553+
/// \brief Represents an explicit template argument list in C++, e.g.,
554+
/// the "<int>" in "sort<int>".
555+
/// This is safe to be used inside an AST node, in contrast with
556+
/// TemplateArgumentListInfo.
557+
struct ASTTemplateArgumentListInfo {
558+
/// \brief The source location of the left angle bracket ('<');
559+
SourceLocation LAngleLoc;
560+
561+
/// \brief The source location of the right angle bracket ('>');
562+
SourceLocation RAngleLoc;
563+
564+
/// \brief The number of template arguments in TemplateArgs.
565+
/// The actual template arguments (if any) are stored after the
566+
/// ExplicitTemplateArgumentList structure.
567+
unsigned NumTemplateArgs;
568+
569+
/// \brief Retrieve the template arguments
570+
TemplateArgumentLoc *getTemplateArgs() {
571+
return reinterpret_cast<TemplateArgumentLoc *> (this + 1);
572+
}
573+
574+
/// \brief Retrieve the template arguments
575+
const TemplateArgumentLoc *getTemplateArgs() const {
576+
return reinterpret_cast<const TemplateArgumentLoc *> (this + 1);
577+
}
578+
579+
const TemplateArgumentLoc &operator[](unsigned I) const {
580+
return getTemplateArgs()[I];
581+
}
582+
583+
static const ASTTemplateArgumentListInfo *Create(ASTContext &C,
584+
const TemplateArgumentListInfo &List);
585+
586+
void initializeFrom(const TemplateArgumentListInfo &List);
587+
void initializeFrom(const TemplateArgumentListInfo &List,
588+
bool &Dependent, bool &InstantiationDependent,
589+
bool &ContainsUnexpandedParameterPack);
590+
void copyInto(TemplateArgumentListInfo &List) const;
591+
static std::size_t sizeFor(unsigned NumTemplateArgs);
592+
static std::size_t sizeFor(const TemplateArgumentListInfo &List);
593+
};
594+
549595
const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
550596
const TemplateArgument &Arg);
551597

clang/lib/AST/Decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1999,7 +1999,7 @@ FunctionDecl::getTemplateSpecializationArgs() const {
19991999
return 0;
20002000
}
20012001

2002-
const TemplateArgumentListInfo *
2002+
const ASTTemplateArgumentListInfo *
20032003
FunctionDecl::getTemplateSpecializationArgsAsWritten() const {
20042004
if (FunctionTemplateSpecializationInfo *Info
20052005
= TemplateOrSpecialization

clang/lib/AST/DeclTemplate.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,24 @@ TemplateArgumentList::CreateCopy(ASTContext &Context,
563563
return new (Mem) TemplateArgumentList(StoredArgs, NumArgs, true);
564564
}
565565

566+
FunctionTemplateSpecializationInfo *
567+
FunctionTemplateSpecializationInfo::Create(ASTContext &C, FunctionDecl *FD,
568+
FunctionTemplateDecl *Template,
569+
TemplateSpecializationKind TSK,
570+
const TemplateArgumentList *TemplateArgs,
571+
const TemplateArgumentListInfo *TemplateArgsAsWritten,
572+
SourceLocation POI) {
573+
const ASTTemplateArgumentListInfo *ArgsAsWritten = 0;
574+
if (TemplateArgsAsWritten)
575+
ArgsAsWritten = ASTTemplateArgumentListInfo::Create(C,
576+
*TemplateArgsAsWritten);
577+
578+
return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
579+
TemplateArgs,
580+
ArgsAsWritten,
581+
POI);
582+
}
583+
566584
//===----------------------------------------------------------------------===//
567585
// ClassTemplateSpecializationDecl Implementation
568586
//===----------------------------------------------------------------------===//

clang/lib/AST/Expr.cpp

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -130,57 +130,6 @@ SourceLocation Expr::getExprLoc() const {
130130
// Primary Expressions.
131131
//===----------------------------------------------------------------------===//
132132

133-
void ASTTemplateArgumentListInfo::initializeFrom(
134-
const TemplateArgumentListInfo &Info) {
135-
LAngleLoc = Info.getLAngleLoc();
136-
RAngleLoc = Info.getRAngleLoc();
137-
NumTemplateArgs = Info.size();
138-
139-
TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
140-
for (unsigned i = 0; i != NumTemplateArgs; ++i)
141-
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
142-
}
143-
144-
void ASTTemplateArgumentListInfo::initializeFrom(
145-
const TemplateArgumentListInfo &Info,
146-
bool &Dependent,
147-
bool &InstantiationDependent,
148-
bool &ContainsUnexpandedParameterPack) {
149-
LAngleLoc = Info.getLAngleLoc();
150-
RAngleLoc = Info.getRAngleLoc();
151-
NumTemplateArgs = Info.size();
152-
153-
TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
154-
for (unsigned i = 0; i != NumTemplateArgs; ++i) {
155-
Dependent = Dependent || Info[i].getArgument().isDependent();
156-
InstantiationDependent = InstantiationDependent ||
157-
Info[i].getArgument().isInstantiationDependent();
158-
ContainsUnexpandedParameterPack
159-
= ContainsUnexpandedParameterPack ||
160-
Info[i].getArgument().containsUnexpandedParameterPack();
161-
162-
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
163-
}
164-
}
165-
166-
void ASTTemplateArgumentListInfo::copyInto(
167-
TemplateArgumentListInfo &Info) const {
168-
Info.setLAngleLoc(LAngleLoc);
169-
Info.setRAngleLoc(RAngleLoc);
170-
for (unsigned I = 0; I != NumTemplateArgs; ++I)
171-
Info.addArgument(getTemplateArgs()[I]);
172-
}
173-
174-
std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) {
175-
return sizeof(ASTTemplateArgumentListInfo) +
176-
sizeof(TemplateArgumentLoc) * NumTemplateArgs;
177-
}
178-
179-
std::size_t ASTTemplateArgumentListInfo::sizeFor(
180-
const TemplateArgumentListInfo &Info) {
181-
return sizeFor(Info.size());
182-
}
183-
184133
/// \brief Compute the type-, value-, and instantiation-dependence of a
185134
/// declaration reference
186135
/// based on the declaration being referenced.

clang/lib/AST/TemplateBase.cpp

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,3 +530,65 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
530530

531531
return DB;
532532
}
533+
534+
const ASTTemplateArgumentListInfo *
535+
ASTTemplateArgumentListInfo::Create(ASTContext &C,
536+
const TemplateArgumentListInfo &List) {
537+
std::size_t size = sizeof(CXXDependentScopeMemberExpr) +
538+
ASTTemplateArgumentListInfo::sizeFor(List);
539+
void *Mem = C.Allocate(size, llvm::alignOf<ASTTemplateArgumentListInfo>());
540+
ASTTemplateArgumentListInfo *TAI = new (Mem) ASTTemplateArgumentListInfo();
541+
TAI->initializeFrom(List);
542+
return TAI;
543+
}
544+
545+
void ASTTemplateArgumentListInfo::initializeFrom(
546+
const TemplateArgumentListInfo &Info) {
547+
LAngleLoc = Info.getLAngleLoc();
548+
RAngleLoc = Info.getRAngleLoc();
549+
NumTemplateArgs = Info.size();
550+
551+
TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
552+
for (unsigned i = 0; i != NumTemplateArgs; ++i)
553+
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
554+
}
555+
556+
void ASTTemplateArgumentListInfo::initializeFrom(
557+
const TemplateArgumentListInfo &Info,
558+
bool &Dependent,
559+
bool &InstantiationDependent,
560+
bool &ContainsUnexpandedParameterPack) {
561+
LAngleLoc = Info.getLAngleLoc();
562+
RAngleLoc = Info.getRAngleLoc();
563+
NumTemplateArgs = Info.size();
564+
565+
TemplateArgumentLoc *ArgBuffer = getTemplateArgs();
566+
for (unsigned i = 0; i != NumTemplateArgs; ++i) {
567+
Dependent = Dependent || Info[i].getArgument().isDependent();
568+
InstantiationDependent = InstantiationDependent ||
569+
Info[i].getArgument().isInstantiationDependent();
570+
ContainsUnexpandedParameterPack
571+
= ContainsUnexpandedParameterPack ||
572+
Info[i].getArgument().containsUnexpandedParameterPack();
573+
574+
new (&ArgBuffer[i]) TemplateArgumentLoc(Info[i]);
575+
}
576+
}
577+
578+
void ASTTemplateArgumentListInfo::copyInto(
579+
TemplateArgumentListInfo &Info) const {
580+
Info.setLAngleLoc(LAngleLoc);
581+
Info.setRAngleLoc(RAngleLoc);
582+
for (unsigned I = 0; I != NumTemplateArgs; ++I)
583+
Info.addArgument(getTemplateArgs()[I]);
584+
}
585+
586+
std::size_t ASTTemplateArgumentListInfo::sizeFor(unsigned NumTemplateArgs) {
587+
return sizeof(ASTTemplateArgumentListInfo) +
588+
sizeof(TemplateArgumentLoc) * NumTemplateArgs;
589+
}
590+
591+
std::size_t ASTTemplateArgumentListInfo::sizeFor(
592+
const TemplateArgumentListInfo &Info) {
593+
return sizeFor(Info.size());
594+
}

clang/lib/Sema/SemaTemplate.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5522,12 +5522,10 @@ Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
55225522
// Take copies of (semantic and syntactic) template argument lists.
55235523
const TemplateArgumentList* TemplArgs = new (Context)
55245524
TemplateArgumentList(Specialization->getTemplateSpecializationArgs());
5525-
const TemplateArgumentListInfo* TemplArgsAsWritten = ExplicitTemplateArgs
5526-
? new (Context) TemplateArgumentListInfo(*ExplicitTemplateArgs) : 0;
55275525
FD->setFunctionTemplateSpecialization(Specialization->getPrimaryTemplate(),
55285526
TemplArgs, /*InsertPos=*/0,
55295527
SpecInfo->getTemplateSpecializationKind(),
5530-
TemplArgsAsWritten);
5528+
ExplicitTemplateArgs);
55315529
FD->setStorageClass(Specialization->getStorageClass());
55325530

55335531
// The "previous declaration" for this function template specialization is

clang/lib/Serialization/ASTReaderDecl.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
373373
// Template args as written.
374374
SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
375375
SourceLocation LAngleLoc, RAngleLoc;
376-
if (Record[Idx++]) { // TemplateArgumentsAsWritten != 0
376+
bool HasTemplateArgumentsAsWritten = Record[Idx++];
377+
if (HasTemplateArgumentsAsWritten) {
377378
unsigned NumTemplateArgLocs = Record[Idx++];
378379
TemplArgLocs.reserve(NumTemplateArgLocs);
379380
for (unsigned i=0; i != NumTemplateArgLocs; ++i)
@@ -389,14 +390,14 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
389390
ASTContext &C = Reader.getContext();
390391
TemplateArgumentList *TemplArgList
391392
= TemplateArgumentList::CreateCopy(C, TemplArgs.data(), TemplArgs.size());
392-
TemplateArgumentListInfo *TemplArgsInfo
393-
= new (C) TemplateArgumentListInfo(LAngleLoc, RAngleLoc);
393+
TemplateArgumentListInfo TemplArgsInfo(LAngleLoc, RAngleLoc);
394394
for (unsigned i=0, e = TemplArgLocs.size(); i != e; ++i)
395-
TemplArgsInfo->addArgument(TemplArgLocs[i]);
395+
TemplArgsInfo.addArgument(TemplArgLocs[i]);
396396
FunctionTemplateSpecializationInfo *FTInfo
397397
= FunctionTemplateSpecializationInfo::Create(C, FD, Template, TSK,
398398
TemplArgList,
399-
TemplArgsInfo, POI);
399+
HasTemplateArgumentsAsWritten ? &TemplArgsInfo : 0,
400+
POI);
400401
FD->TemplateOrSpecialization = FTInfo;
401402

402403
if (FD->isCanonicalDecl()) { // if canonical add to template's set.

0 commit comments

Comments
 (0)