https://github.com/hokein created https://github.com/llvm/llvm-project/pull/114213
This patch extends the filtering heuristic to apply for the Lifetimebound code path. This will suppress a common false positive: ``` namespace std { template<typename T> struct unique_ptr { T &operator*(); T *get() const [[clang::lifetimebound]]; }; } // namespace std struct X { X(std::unique_ptr<int> up) : pointer(up.get()), owner(std::move(up)) {} int *pointer; std::unique_ptr<int> owner; }; ``` See #112751. >From ebd9182e4ae3486fd2e2edd55c7c683605f33294 Mon Sep 17 00:00:00 2001 From: Haojian Wu <hokein...@gmail.com> Date: Wed, 30 Oct 2024 12:42:15 +0100 Subject: [PATCH] [clang] Suppress a dangling false positive when owner is moved in the member initializer. This patch extends the filtering heuristic to apply for the Lifetimebound code path. This will suppress a common false positive: ``` namespace std { template<typename T> struct unique_ptr { T &operator*(); T *get() const [[clang::lifetimebound]]; }; } // namespace std struct X { X(std::unique_ptr<int> up) : pointer(up.get()), owner(std::move(up)) {} int *pointer; std::unique_ptr<int> owner; }; ``` --- clang/lib/Sema/CheckExprLifetime.cpp | 6 +++--- clang/test/Sema/warn-lifetime-analysis-nocfg.cpp | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index aa0a2e223e708f..33d308fe7bdb60 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -1261,12 +1261,12 @@ static void checkExprLifetimeImpl(Sema &SemaRef, if (pathContainsInit(Path)) return false; + auto *DRE = dyn_cast<DeclRefExpr>(L); // Suppress false positives for code like the one below: - // Ctor(unique_ptr<T> up) : member(*up), member2(move(up)) {} - if (IsLocalGslOwner && pathOnlyHandlesGslPointer(Path)) + // Ctor(unique_ptr<T> up) : pointer(up.get()), owner(move(up)) {} + if (DRE && isRecordWithAttr<OwnerAttr>(DRE->getType())) return false; - auto *DRE = dyn_cast<DeclRefExpr>(L); auto *VD = DRE ? dyn_cast<VarDecl>(DRE->getDecl()) : nullptr; if (!VD) { // A member was initialized to a local block. diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index 688f55edfe84df..6a2af01ea5116c 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -384,6 +384,19 @@ struct X { std::unique_ptr<int> pointer; }; +struct [[gsl::Owner]] XOwner { + int* get() const [[clang::lifetimebound]]; +}; +struct X2 { + // A common usage that moves the passing owner to the class. + // verify no warning on this case. + X2(XOwner owner) : + pointee(owner.get()), + owner(std::move(owner)) {} + int* pointee; + XOwner owner; +}; + std::vector<int>::iterator getIt(); std::vector<int> getVec(); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits