[clang] [clang] Detect dangling assignment for "Container<Pointer>" case. (PR #108205)

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 11 05:15:09 PDT 2024


https://github.com/hokein created https://github.com/llvm/llvm-project/pull/108205

This is a follow up of https://github.com/llvm/llvm-project/pull/107213, supporting the assignment case.

With this patch, clang now diagnoses cases where a dangling `container<pointer>` is assigned, e.g.

```
void test() {
   std::vector<string_view> v;
   v = {std::string()}; // dangling
}
```

Fixes #100526

>From 041b36967842cf4cb8942e4cbfe729d8987f1a0c Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Wed, 11 Sep 2024 13:27:28 +0200
Subject: [PATCH] [clang] Detect dangling assignment for "Container<Pointer>"
 case.

---
 clang/docs/ReleaseNotes.rst                      |  2 ++
 clang/lib/Sema/CheckExprLifetime.cpp             |  3 ++-
 clang/test/Sema/warn-lifetime-analysis-nocfg.cpp | 10 ++++++++--
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 59ccdf1e15cd81..43f0d6eb4f2edc 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -300,6 +300,8 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses cases where a dangling ``GSLOwner<GSLPointer>`` object is constructed, e.g. ``std::vector<string_view> v = {std::string()};`` (#GH100526).
 
+- Clang now diagnoses cases where a dangling ``GSLOwner<GSLPointer>`` object is assigned, e.g. ``v = {std::string()};`` (#GH100526).
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp
index c8e703036c132c..6fc1d4d0aae259 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -982,7 +982,8 @@ static bool shouldRunGSLAssignmentAnalysis(const Sema &SemaRef,
       diag::warn_dangling_lifetime_pointer_assignment, SourceLocation());
   return (EnableGSLAssignmentWarnings &&
           (isRecordWithAttr<PointerAttr>(Entity.LHS->getType()) ||
-           isAssignmentOperatorLifetimeBound(Entity.AssignmentOperator)));
+           isAssignmentOperatorLifetimeBound(Entity.AssignmentOperator) ||
+           isContainerOfPointer(Entity.LHS->getType()->getAsRecordDecl())));
 }
 
 static void checkExprLifetimeImpl(Sema &SemaRef,
diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
index 234e06f069074b..d744140800f595 100644
--- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
+++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
@@ -601,17 +601,23 @@ void test() {
   std::optional<std::string_view> o4 = std::optional<std::string_view>(s); 
 
   // FIXME: should work for assignment cases
-  v1 = {std::string()};
-  o1 = std::string();
+  v1 = {std::string()}; // expected-warning {{object backing the pointer}}
+  o1 = std::string(); // expected-warning {{object backing the pointer}}
 
   // no warning on copying pointers.
   std::vector<std::string_view> n1 = {std::string_view()};
+  n1 = {std::string_view()};
   std::optional<std::string_view> n2 = {std::string_view()};
+  n2 = {std::string_view()};
   std::optional<std::string_view> n3 = std::string_view();
+  n3 = std::string_view();
   std::optional<std::string_view> n4 = std::make_optional(std::string_view());
+  n4 = std::make_optional(std::string_view());
   const char* b = "";
   std::optional<std::string_view> n5 = std::make_optional(b);
+  n5 = std::make_optional(b);
   std::optional<std::string_view> n6 = std::make_optional("test");
+  n6 = std::make_optional("test");
 }
 
 std::vector<std::string_view> test2(int i) {



More information about the cfe-commits mailing list