Skip to content

Commit 352f868

Browse files
authored
[clang] Fix incorrect inferred lifetime_capture_by attr on STL (#118013)
We incorrectly annotate the iterator parameter for `insert` method (`void insert(const_iterator, const value_type& value)`), because iterator is also a gsl-pointer type. This patch fixes it.
1 parent 9b2ec87 commit 352f868

File tree

2 files changed

+30
-39
lines changed

2 files changed

+30
-39
lines changed

clang/lib/Sema/SemaAttr.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,12 @@ void Sema::inferLifetimeCaptureByAttribute(FunctionDecl *FD) {
287287
if (PVD->hasAttr<LifetimeCaptureByAttr>())
288288
return;
289289
for (ParmVarDecl *PVD : MD->parameters()) {
290-
if (sema::isPointerLikeType(PVD->getType().getNonReferenceType())) {
290+
// Methods in standard containers that capture values typically accept
291+
// reference-type parameters, e.g., `void push_back(const T& value)`.
292+
// We only apply the lifetime_capture_by attribute to parameters of
293+
// pointer-like reference types (`const T&`, `T&&`).
294+
if (PVD->getType()->isReferenceType() &&
295+
sema::isPointerLikeType(PVD->getType().getNonReferenceType())) {
291296
int CaptureByThis[] = {LifetimeCaptureByAttr::THIS};
292297
PVD->addAttr(
293298
LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1));

clang/test/AST/attr-lifetime-capture-by.cpp

Lines changed: 24 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -37,67 +37,53 @@ struct vector {
3737
struct [[gsl::Pointer()]] View {};
3838
std::vector<View> views;
3939
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation
40-
// CHECK: TemplateArgument type 'View'
41-
// CHECK-NOT: LifetimeCaptureByAttr
4240

4341
// CHECK: CXXMethodDecl {{.*}} push_back 'void (const View &)'
44-
// CHECK: ParmVarDecl {{.*}} 'const View &'
45-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
46-
// CHECK-NOT: LifetimeCaptureByAttr
42+
// CHECK-NEXT: ParmVarDecl {{.*}} 'const View &'
43+
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit
4744

4845
// CHECK: CXXMethodDecl {{.*}} push_back 'void (View &&)'
49-
// CHECK: ParmVarDecl {{.*}} 'View &&'
50-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
46+
// CHECK-NEXT: ParmVarDecl {{.*}} 'View &&'
47+
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit
5148

5249
// CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, View &&)'
53-
// CHECK: ParmVarDecl {{.*}} 'iterator'
54-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
55-
// CHECK: ParmVarDecl {{.*}} 'View &&'
56-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
57-
// CHECK-NOT: LifetimeCaptureByAttr
50+
// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator'
51+
// CHECK-NEXT: ParmVarDecl {{.*}} 'View &&'
52+
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit
5853

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

6558
// CHECK: CXXMethodDecl {{.*}} push_back 'void (const ViewTemplate<int> &)'
66-
// CHECK: ParmVarDecl {{.*}} 'const ViewTemplate<int> &'
67-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
59+
// CHECK-NEXT: ParmVarDecl {{.*}} 'const ViewTemplate<int> &'
60+
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit
6861
// CHECK-NOT: LifetimeCaptureByAttr
6962

7063
// CHECK: CXXMethodDecl {{.*}} push_back 'void (ViewTemplate<int> &&)'
71-
// CHECK: ParmVarDecl {{.*}} 'ViewTemplate<int> &&'
72-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
64+
// CHECK-NEXT: ParmVarDecl {{.*}} 'ViewTemplate<int> &&'
65+
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit
7366

7467
// CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, ViewTemplate<int> &&)'
75-
// CHECK: ParmVarDecl {{.*}} 'iterator'
76-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
77-
// CHECK: ParmVarDecl {{.*}} 'ViewTemplate<int> &&'
78-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
79-
// CHECK-NOT: LifetimeCaptureByAttr
68+
// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator'
69+
// CHECK-NEXT: ParmVarDecl {{.*}} 'ViewTemplate<int> &&'
70+
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit
8071

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

8675
// CHECK: CXXMethodDecl {{.*}} push_back 'void (int *const &)'
87-
// CHECK: ParmVarDecl {{.*}} 'int *const &'
88-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
89-
// CHECK-NOT: LifetimeCaptureByAttr
76+
// CHECK-NEXT: ParmVarDecl {{.*}} 'int *const &'
77+
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit
9078

9179
// CHECK: CXXMethodDecl {{.*}} push_back 'void (int *&&)'
92-
// CHECK: ParmVarDecl {{.*}} 'int *&&'
93-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
80+
// CHECK-NEXT: ParmVarDecl {{.*}} 'int *&&'
81+
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit
9482

9583
// CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, int *&&)'
96-
// CHECK: ParmVarDecl {{.*}} 'iterator'
97-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
98-
// CHECK: ParmVarDecl {{.*}} 'int *&&'
99-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
100-
// CHECK-NOT: LifetimeCaptureByAttr
84+
// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator'
85+
// CHECK-NEXT: ParmVarDecl {{.*}} 'int *&&'
86+
// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit
10187

10288
std::vector<int> ints;
10389
// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation
@@ -110,6 +96,6 @@ std::vector<int> ints;
11096
// CHECK-NOT: LifetimeCaptureByAttr
11197

11298
// CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, int &&)'
113-
// CHECK: ParmVarDecl {{.*}} 'iterator'
114-
// CHECK: LifetimeCaptureByAttr {{.*}} Implicit
99+
// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator'
100+
// CHECK-NEXT: ParmVarDecl {{.*}} 'int &&'
115101
// CHECK-NOT: LifetimeCaptureByAttr

0 commit comments

Comments
 (0)