Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion clang/lib/Sema/SemaAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,12 @@ void Sema::inferLifetimeCaptureByAttribute(FunctionDecl *FD) {
if (PVD->hasAttr<LifetimeCaptureByAttr>())
return;
for (ParmVarDecl *PVD : MD->parameters()) {
if (sema::isPointerLikeType(PVD->getType().getNonReferenceType())) {
// Methods in standard containers that capture values typically accept
// reference-type parameters, e.g., `void push_back(const T& value)`.
// We only apply the lifetime_capture_by attribute to parameters of
// pointer-like reference types (`const T&`, `T&&`).
if (PVD->getType()->isReferenceType() &&
sema::isPointerLikeType(PVD->getType().getNonReferenceType())) {
int CaptureByThis[] = {LifetimeCaptureByAttr::THIS};
PVD->addAttr(
LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1));
Expand Down
66 changes: 28 additions & 38 deletions clang/test/AST/attr-lifetime-capture-by.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,67 +37,56 @@ struct vector {
struct [[gsl::Pointer()]] View {};
std::vector<View> views;
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation
// CHECK: TemplateArgument type 'View'
// CHECK-NOT: LifetimeCaptureByAttr

// CHECK: CXXMethodDecl {{.*}} push_back 'void (const View &)'
// CHECK: ParmVarDecl {{.*}} 'const View &'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NOT: LifetimeCaptureByAttr
// CHECK-NEXT: ParmVarDecl {{.*}} 'const View &'
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit

// CHECK: CXXMethodDecl {{.*}} push_back 'void (View &&)'
// CHECK: ParmVarDecl {{.*}} 'View &&'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NEXT: ParmVarDecl {{.*}} 'View &&'
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit

// CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, View &&)'
// CHECK: ParmVarDecl {{.*}} 'iterator'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK: ParmVarDecl {{.*}} 'View &&'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NOT: LifetimeCaptureByAttr
// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator'
// CHECK-NOT: LifetimeCaptureByAttr {{.*}} Implicit
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe skip this line if CHECK-NEXT is possible.
same in line 70, 87

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, right, this is even better. Done.

// CHECK-NEXT: ParmVarDecl {{.*}} 'View &&'
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit

template <class T> struct [[gsl::Pointer()]] ViewTemplate {};
std::vector<ViewTemplate<int>> templated_views;
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation
// CHECK: TemplateArgument type 'ViewTemplate<int>'
// CHECK-NOT: LifetimeCaptureByAttr
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation

// CHECK: CXXMethodDecl {{.*}} push_back 'void (const ViewTemplate<int> &)'
// CHECK: ParmVarDecl {{.*}} 'const ViewTemplate<int> &'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NEXT: ParmVarDecl {{.*}} 'const ViewTemplate<int> &'
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NOT: LifetimeCaptureByAttr

// CHECK: CXXMethodDecl {{.*}} push_back 'void (ViewTemplate<int> &&)'
// CHECK: ParmVarDecl {{.*}} 'ViewTemplate<int> &&'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NEXT: ParmVarDecl {{.*}} 'ViewTemplate<int> &&'
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit

// CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, ViewTemplate<int> &&)'
// CHECK: ParmVarDecl {{.*}} 'iterator'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK: ParmVarDecl {{.*}} 'ViewTemplate<int> &&'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NOT: LifetimeCaptureByAttr
// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator'
// CHECK-NOT: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NEXT: ParmVarDecl {{.*}} 'ViewTemplate<int> &&'
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit

std::vector<int*> pointers;
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation
// CHECK: TemplateArgument type 'int *'
// CHECK-NOT: LifetimeCaptureByAttr

// CHECK: CXXMethodDecl {{.*}} push_back 'void (int *const &)'
// CHECK: ParmVarDecl {{.*}} 'int *const &'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NOT: LifetimeCaptureByAttr
// CHECK-NEXT: ParmVarDecl {{.*}} 'int *const &'
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit

// CHECK: CXXMethodDecl {{.*}} push_back 'void (int *&&)'
// CHECK: ParmVarDecl {{.*}} 'int *&&'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NEXT: ParmVarDecl {{.*}} 'int *&&'
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit

// CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, int *&&)'
// CHECK: ParmVarDecl {{.*}} 'iterator'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK: ParmVarDecl {{.*}} 'int *&&'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NOT: LifetimeCaptureByAttr
// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator'
// CHECK-NOT: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NEXT: ParmVarDecl {{.*}} 'int *&&'
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit

std::vector<int> ints;
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation
Expand All @@ -110,6 +99,7 @@ std::vector<int> ints;
// CHECK-NOT: LifetimeCaptureByAttr

// CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, int &&)'
// CHECK: ParmVarDecl {{.*}} 'iterator'
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator'
// CHECK-NOT: LifetimeCaptureByAttr {{.*}} Implicit
// CHECK-NEXT: ParmVarDecl {{.*}} 'int &&'
// CHECK-NOT: LifetimeCaptureByAttr