Skip to content

Commit 85e0870

Browse files
committed
Fix a newly-found false positive.
1 parent 21eec03 commit 85e0870

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

clang/lib/Sema/CheckExprLifetime.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,8 @@ static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
340340
if (Callee->getReturnType()->isReferenceType()) {
341341
if (!Callee->getIdentifier()) {
342342
auto OO = Callee->getOverloadedOperator();
343+
if (!Callee->getParent()->hasAttr<OwnerAttr>())
344+
return false;
343345
return OO == OverloadedOperatorKind::OO_Subscript ||
344346
OO == OverloadedOperatorKind::OO_Star;
345347
}

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,12 @@ struct reference_wrapper {
252252

253253
template<typename T>
254254
reference_wrapper<T> ref(T& t) noexcept;
255+
256+
template <typename T>
257+
struct [[gsl::Pointer]] iterator {
258+
T& operator*() const;
259+
};
260+
255261
}
256262

257263
struct Unannotated {
@@ -852,4 +858,28 @@ Pointer test3(Bar bar) {
852858
return bar; // expected-warning {{address of stack}}
853859
}
854860

861+
template<typename T>
862+
struct MySpan {
863+
MySpan(const std::vector<T>& v);
864+
using iterator = std::iterator<T>;
865+
iterator begin() const [[clang::lifetimebound]];
866+
};
867+
template <typename T>
868+
typename MySpan<T>::iterator ReturnFirstIt(const MySpan<T>& v [[clang::lifetimebound]]);
869+
870+
void test4() {
871+
std::vector<int> v{1};
872+
// MySpan<T> doesn't own any underlying T objects, the pointee object of
873+
// the MySpan iterator is still alive when the whole span is destroyed, thus
874+
// no diagnostic.
875+
const int& t1 = *MySpan<int>(v).begin();
876+
const int& t2 = *ReturnFirstIt(MySpan<int>(v));
877+
// Ideally, we would diagnose the following case, but due to implementation
878+
// constraints, we do not.
879+
const int& t4 = *MySpan<int>(std::vector<int>{}).begin();
880+
881+
auto it1 = MySpan<int>(v).begin(); // expected-warning {{temporary whose address is use}}
882+
auto it2 = ReturnFirstIt(MySpan<int>(v)); // expected-warning {{temporary whose address is used}}
883+
}
884+
855885
} // namespace LifetimeboundInterleave

0 commit comments

Comments
 (0)