Author: Haojian Wu Date: 2024-11-29T09:23:27+01:00 New Revision: 352f8688d0ca250c9e8774321f6c3bcd4298cc09
URL: https://github.com/llvm/llvm-project/commit/352f8688d0ca250c9e8774321f6c3bcd4298cc09 DIFF: https://github.com/llvm/llvm-project/commit/352f8688d0ca250c9e8774321f6c3bcd4298cc09.diff LOG: [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. Added: Modified: clang/lib/Sema/SemaAttr.cpp clang/test/AST/attr-lifetime-capture-by.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index b0849c74e375ed..d3cf42251be2e7 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -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)); diff --git a/clang/test/AST/attr-lifetime-capture-by.cpp b/clang/test/AST/attr-lifetime-capture-by.cpp index c3afe267301ad7..debad9b7204d72 100644 --- a/clang/test/AST/attr-lifetime-capture-by.cpp +++ b/clang/test/AST/attr-lifetime-capture-by.cpp @@ -37,67 +37,53 @@ 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-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-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-NEXT: ParmVarDecl {{.*}} 'int *&&' +// CHECK-NEXT: LifetimeCaptureByAttr {{.*}} Implicit std::vector<int> ints; // CHECK: ClassTemplateSpecializationDecl {{.*}} struct vector definition implicit_instantiation @@ -110,6 +96,6 @@ std::vector<int> ints; // CHECK-NOT: LifetimeCaptureByAttr // CHECK: CXXMethodDecl {{.*}} insert 'void (iterator, int &&)' -// CHECK: ParmVarDecl {{.*}} 'iterator' -// CHECK: LifetimeCaptureByAttr {{.*}} Implicit +// CHECK-NEXT: ParmVarDecl {{.*}} 'iterator' +// CHECK-NEXT: ParmVarDecl {{.*}} 'int &&' // CHECK-NOT: LifetimeCaptureByAttr _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits