Skip to content

Commit f484a04

Browse files
authored
[clang] Suppress a dangling false positive when owner is moved in member initializer. (#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 #114201.
1 parent 83ce977 commit f484a04

File tree

2 files changed

+16
-3
lines changed

2 files changed

+16
-3
lines changed

clang/lib/Sema/CheckExprLifetime.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1261,12 +1261,12 @@ static void checkExprLifetimeImpl(Sema &SemaRef,
12611261
if (pathContainsInit(Path))
12621262
return false;
12631263

1264+
auto *DRE = dyn_cast<DeclRefExpr>(L);
12641265
// Suppress false positives for code like the one below:
1265-
// Ctor(unique_ptr<T> up) : member(*up), member2(move(up)) {}
1266-
if (IsLocalGslOwner && pathOnlyHandlesGslPointer(Path))
1266+
// Ctor(unique_ptr<T> up) : pointer(up.get()), owner(move(up)) {}
1267+
if (DRE && isRecordWithAttr<OwnerAttr>(DRE->getType()))
12671268
return false;
12681269

1269-
auto *DRE = dyn_cast<DeclRefExpr>(L);
12701270
auto *VD = DRE ? dyn_cast<VarDecl>(DRE->getDecl()) : nullptr;
12711271
if (!VD) {
12721272
// A member was initialized to a local block.

clang/test/Sema/warn-lifetime-analysis-nocfg.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,19 @@ struct X {
384384
std::unique_ptr<int> pointer;
385385
};
386386

387+
struct [[gsl::Owner]] XOwner {
388+
int* get() const [[clang::lifetimebound]];
389+
};
390+
struct X2 {
391+
// A common usage that moves the passing owner to the class.
392+
// verify no warning on this case.
393+
X2(XOwner owner) :
394+
pointee(owner.get()),
395+
owner(std::move(owner)) {}
396+
int* pointee;
397+
XOwner owner;
398+
};
399+
387400
std::vector<int>::iterator getIt();
388401
std::vector<int> getVec();
389402

0 commit comments

Comments
 (0)