[clang] [LifetimeSafety] Track dereference operators for GSL pointers in STL (PR #176643)
Utkarsh Saxena via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 19 02:59:14 PST 2026
https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/176643
>From 3dc9236abc9d3470124d60cb5ee8531be8ef3937 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Sun, 18 Jan 2026 11:49:39 +0000
Subject: [PATCH] range based for loops
---
.../LifetimeSafety/LifetimeAnnotations.cpp | 7 +++
.../Sema/warn-lifetime-analysis-nocfg.cpp | 58 +++++++++++++++++--
2 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
index 2772fe20de19b..9843930999a0f 100644
--- a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp
@@ -99,6 +99,13 @@ bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
if (!isGslPointerType(Callee->getFunctionObjectParameterType()) &&
!isGslOwnerType(Callee->getFunctionObjectParameterType()))
return false;
+
+ // Track dereference operator for GSL pointers in STL.
+ if (isGslPointerType(Callee->getFunctionObjectParameterType()))
+ if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Callee))
+ if (MD->getOverloadedOperator() == OverloadedOperatorKind::OO_Star)
+ return true;
+
if (isPointerLikeType(Callee->getReturnType())) {
if (!Callee->getIdentifier())
return false;
diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
index 7fdc493dbd17a..d7410125f55bb 100644
--- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
+++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
@@ -911,10 +911,13 @@ struct MySpan {
MySpan(const std::vector<T>& v);
~MySpan();
using iterator = std::iterator<T>;
- iterator begin() const [[clang::lifetimebound]];
+ // FIXME: It is not possible to annotate accessor methods of non-owning view types.
+ // Clang should provide another annotation to mark such functions as 'transparent'.
+ iterator begin() const;
};
+// FIXME: Same as above.
template <typename T>
-typename MySpan<T>::iterator ReturnFirstIt(const MySpan<T>& v [[clang::lifetimebound]]);
+typename MySpan<T>::iterator ReturnFirstIt(const MySpan<T>& v);
void test4() {
std::vector<int> v{1};
@@ -926,15 +929,60 @@ void test4() {
// Ideally, we would diagnose the following case, but due to implementation
// constraints, we do not.
const int& t4 = *MySpan<int>(std::vector<int>{}).begin();
+ use(t1, t2, t4);
- // FIXME: Detect this using the CFG-based lifetime analysis (constructor of a pointer).
- auto it1 = MySpan<int>(v).begin(); // expected-warning {{temporary whose address is use}}
- auto it2 = ReturnFirstIt(MySpan<int>(v)); // expected-warning {{temporary whose address is used}}
+ auto it1 = MySpan<int>(v).begin();
+ auto it2 = ReturnFirstIt(MySpan<int>(v));
use(it1, it2);
}
} // namespace LifetimeboundInterleave
+namespace range_based_for_loop_variables {
+std::string_view test_view_loop_var(std::vector<std::string> strings) {
+ for (std::string_view s : strings) { // cfg-warning {{address of stack memory is returned later}}
+ return s; //cfg-note {{returned here}}
+ }
+ return "";
+}
+
+const char* test_view_loop_var_with_data(std::vector<std::string> strings) {
+ for (std::string_view s : strings) { // cfg-warning {{address of stack memory is returned later}}
+ return s.data(); //cfg-note {{returned here}}
+ }
+ return "";
+}
+
+std::string_view test_no_error_for_views(std::vector<std::string_view> views) {
+ for (std::string_view s : views) {
+ return s;
+ }
+ return "";
+}
+
+std::string_view test_string_ref_var(std::vector<std::string> strings) {
+ for (const std::string& s : strings) { // cfg-warning {{address of stack memory is returned later}}
+ return s; //cfg-note {{returned here}}
+ }
+ return "";
+}
+
+std::string_view test_opt_strings(std::optional<std::vector<std::string>> strings_or) {
+ for (const std::string& s : *strings_or) { // cfg-warning {{address of stack memory is returned later}}
+ return s; //cfg-note {{returned here}}
+ }
+ return "";
+}
+} // namespace range_based_for_loop_variables
+
+namespace iterator_arrow {
+std::string_view test() {
+ std::vector<std::string> strings;
+ // FIXME: Track operator-> of iterators.
+ return strings.begin()->data();
+}
+} // namespace iterator_arrow
+
namespace GH120206 {
struct S {
std::string_view s;
More information about the cfe-commits
mailing list