Skip to content

Commit 12ccb62

Browse files
authored
[clang] Add a common definition of isPointerLikeType for lifetime analysis (#117315)
Also checks for annotation for template specializations which sometimes may not have the annotation attached.
1 parent 392bd34 commit 12ccb62

File tree

3 files changed

+17
-21
lines changed

3 files changed

+17
-21
lines changed

clang/lib/Sema/CheckExprLifetime.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "CheckExprLifetime.h"
1010
#include "clang/AST/Decl.h"
1111
#include "clang/AST/Expr.h"
12+
#include "clang/AST/Type.h"
1213
#include "clang/Basic/DiagnosticSema.h"
1314
#include "clang/Sema/Initialization.h"
1415
#include "clang/Sema/Sema.h"
@@ -253,9 +254,17 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
253254
LocalVisitor Visit);
254255

255256
template <typename T> static bool isRecordWithAttr(QualType Type) {
256-
if (auto *RD = Type->getAsCXXRecordDecl())
257-
return RD->hasAttr<T>();
258-
return false;
257+
auto *RD = Type->getAsCXXRecordDecl();
258+
if (!RD)
259+
return false;
260+
if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
261+
RD = CTSD->getSpecializedTemplate()->getTemplatedDecl();
262+
return RD->hasAttr<T>();
263+
}
264+
265+
bool isPointerLikeType(QualType QT) {
266+
return isRecordWithAttr<PointerAttr>(QT) || QT->isPointerType() ||
267+
QT->isNullPtrType();
259268
}
260269

261270
// Decl::isInStdNamespace will return false for iterators in some STL
@@ -276,11 +285,6 @@ static bool isInStlNamespace(const Decl *D) {
276285
return DC->isStdNamespace();
277286
}
278287

279-
static bool isPointerLikeType(QualType Type) {
280-
return isRecordWithAttr<PointerAttr>(Type) || Type->isPointerType() ||
281-
Type->isNullPtrType();
282-
}
283-
284288
// Returns true if the given Record decl is a form of `GSLOwner<Pointer>`
285289
// type, e.g. std::vector<string_view>, std::optional<string_view>.
286290
static bool isContainerOfPointer(const RecordDecl *Container) {

clang/lib/Sema/CheckExprLifetime.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818

1919
namespace clang::sema {
2020

21+
// Tells whether the type is annotated with [[gsl::Pointer]] or is a pointer
22+
// type.
23+
bool isPointerLikeType(QualType QT);
24+
2125
/// Describes an entity that is being assigned.
2226
struct AssignedEntity {
2327
// The left-hand side expression of the assignment.

clang/lib/Sema/SemaAttr.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -269,18 +269,6 @@ void Sema::inferLifetimeBoundAttribute(FunctionDecl *FD) {
269269
}
270270
}
271271

272-
static bool isPointerLikeType(QualType QT) {
273-
QT = QT.getNonReferenceType();
274-
if (QT->isPointerType())
275-
return true;
276-
auto *RD = QT->getAsCXXRecordDecl();
277-
if (!RD)
278-
return false;
279-
if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
280-
RD = CTSD->getSpecializedTemplate()->getTemplatedDecl();
281-
return RD->hasAttr<PointerAttr>();
282-
}
283-
284272
void Sema::inferLifetimeCaptureByAttribute(FunctionDecl *FD) {
285273
if (!FD)
286274
return;
@@ -299,7 +287,7 @@ void Sema::inferLifetimeCaptureByAttribute(FunctionDecl *FD) {
299287
if (PVD->hasAttr<LifetimeCaptureByAttr>())
300288
return;
301289
for (ParmVarDecl *PVD : MD->parameters()) {
302-
if (isPointerLikeType(PVD->getType())) {
290+
if (sema::isPointerLikeType(PVD->getType().getNonReferenceType())) {
303291
int CaptureByThis[] = {LifetimeCaptureByAttr::THIS};
304292
PVD->addAttr(
305293
LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1));

0 commit comments

Comments
 (0)