File tree Expand file tree Collapse file tree 5 files changed +33
-11
lines changed Expand file tree Collapse file tree 5 files changed +33
-11
lines changed Original file line number Diff line number Diff line change @@ -281,9 +281,11 @@ template <typename T> static bool isRecordWithAttr(QualType Type) {
281281 return Result;
282282}
283283
284- bool isPointerLikeType (QualType QT) {
285- return isRecordWithAttr<PointerAttr>(QT) || QT->isPointerType () ||
286- QT->isNullPtrType ();
284+ // Tells whether the type is annotated with [[gsl::Pointer]].
285+ bool isGLSPointerType (QualType QT) { return isRecordWithAttr<PointerAttr>(QT); }
286+
287+ static bool isPointerLikeType (QualType QT) {
288+ return isGLSPointerType (QT) || QT->isPointerType () || QT->isNullPtrType ();
287289}
288290
289291// Decl::isInStdNamespace will return false for iterators in some STL
Original file line number Diff line number Diff line change 1818
1919namespace clang ::sema {
2020
21- // Tells whether the type is annotated with [[gsl::Pointer]] or is a pointer
22- // type.
23- bool isPointerLikeType (QualType QT);
21+ // Tells whether the type is annotated with [[gsl::Pointer]].
22+ bool isGLSPointerType (QualType QT);
2423
2524// / Describes an entity that is being assigned.
2625struct AssignedEntity {
Original file line number Diff line number Diff line change @@ -284,7 +284,7 @@ void Sema::inferLifetimeCaptureByAttribute(FunctionDecl *FD) {
284284 // We only apply the lifetime_capture_by attribute to parameters of
285285 // pointer-like reference types (`const T&`, `T&&`).
286286 if (PVD->getType ()->isReferenceType () &&
287- sema::isPointerLikeType (PVD->getType ().getNonReferenceType ())) {
287+ sema::isGLSPointerType (PVD->getType ().getNonReferenceType ())) {
288288 int CaptureByThis[] = {LifetimeCaptureByAttr::THIS};
289289 PVD->addAttr (
290290 LifetimeCaptureByAttr::CreateImplicit (Context, CaptureByThis, 1 ));
Original file line number Diff line number Diff line change @@ -80,16 +80,16 @@ std::vector<int*> pointers;
8080
8181// CHECK: CXXMethodDecl {{.*}} push_back 'void (int *const &)'
8282// CHECK-NEXT: ParmVarDecl {{.*}} 'int *const &'
83- // CHECK-NEXT : LifetimeCaptureByAttr {{.*}} Implicit
83+ // CHECK-NOT : LifetimeCaptureByAttr
8484
8585// CHECK: CXXMethodDecl {{.*}} push_back 'void (int *&&)'
8686// CHECK-NEXT: ParmVarDecl {{.*}} 'int *&&'
87- // CHECK-NEXT : LifetimeCaptureByAttr {{.*}} Implicit
87+ // CHECK-NOT : LifetimeCaptureByAttr
8888
8989// CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, int *&&)'
9090// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator'
9191// CHECK-NEXT: ParmVarDecl {{.*}} 'int *&&'
92- // CHECK-NEXT : LifetimeCaptureByAttr {{.*}} Implicit
92+ // CHECK-NOT : LifetimeCaptureByAttr
9393
9494std::vector<int > ints;
9595// CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation
Original file line number Diff line number Diff line change @@ -406,7 +406,7 @@ void use() {
406406 strings.insert (strings.begin (), std::string ());
407407
408408 std::vector<const std::string*> pointers;
409- pointers.push_back (getLifetimeBoundPointer (std::string ())); // expected-warning {{object whose reference is captured by 'pointers' will be destroyed at the end of the full-expression}}
409+ pointers.push_back (getLifetimeBoundPointer (std::string ()));
410410 pointers.push_back (&local);
411411}
412412
@@ -451,3 +451,24 @@ void test() {
451451 T2 (1 , a); // expected-warning {{object whose reference is captured by}}
452452}
453453} // namespace on_constructor
454+
455+ namespace GH121391 {
456+
457+ struct Foo {};
458+
459+ template <typename T>
460+ struct Container {
461+ const T& tt () [[clang::lifetimebound]];
462+ };
463+ template <typename T>
464+ struct StatusOr {
465+ T* get () [[clang::lifetimebound]];
466+ };
467+ StatusOr<Container<const Foo*>> getContainer ();
468+
469+ void test () {
470+ std::vector<const Foo*> vv;
471+ vv.push_back (getContainer ().get ()->tt ()); // OK
472+ }
473+
474+ } // namespace GH121391
You can’t perform that action at this time.
0 commit comments