[clang] Fix false positive regression for lifetime analysis warning. (#127460)

This fixes a false positive caused by #114044.

For `GSLPointer*` types, it's less clear whether the lifetime issue is
about the GSLPointer object itself or the owner it points to. To avoid
false positives, we take a conservative approach in our heuristic.

Fixes #127195

(This will be backported to release 20).
This commit is contained in:
Haojian Wu 2025-02-17 14:40:31 +01:00 committed by GitHub
parent f4206f92c5
commit 9c49b188b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 29 additions and 2 deletions

View File

@ -1239,11 +1239,12 @@ static AnalysisResult analyzePathForGSLPointer(const IndirectLocalPath &Path,
}
// Check the return type, e.g.
// const GSLOwner& func(const Foo& foo [[clang::lifetimebound]])
// GSLOwner* func(cosnt Foo& foo [[clang::lifetimebound]])
// GSLPointer func(const Foo& foo [[clang::lifetimebound]])
if (FD &&
((FD->getReturnType()->isReferenceType() &&
((FD->getReturnType()->isPointerOrReferenceType() &&
isRecordWithAttr<OwnerAttr>(FD->getReturnType()->getPointeeType())) ||
isPointerLikeType(FD->getReturnType())))
isGLSPointerType(FD->getReturnType())))
return Report;
return Abandon;

View File

@ -61,6 +61,7 @@ struct basic_string_view {
basic_string_view();
basic_string_view(const T *);
const T *begin() const;
const T *data() const;
};
using string_view = basic_string_view<char>;
@ -80,6 +81,7 @@ struct basic_string {
const T *c_str() const;
operator basic_string_view<T> () const;
using const_iterator = iter<T>;
const T *data() const;
};
using string = basic_string<char>;

View File

@ -852,3 +852,27 @@ struct Test {
};
} // namespace GH120543
namespace GH127195 {
template <typename T>
struct StatusOr {
T* operator->() [[clang::lifetimebound]];
T* value() [[clang::lifetimebound]];
};
const char* foo() {
StatusOr<std::string> s;
return s->data(); // expected-warning {{address of stack memory associated with local variable}}
StatusOr<std::string_view> s2;
return s2->data();
StatusOr<StatusOr<std::string_view>> s3;
return s3.value()->value()->data();
// FIXME: nested cases are not supported now.
StatusOr<StatusOr<std::string>> s4;
return s4.value()->value()->data();
}
} // namespace GH127195