[clang] [clang] Don't emit bogus dangling diagnostics when `[[gsl::Owner]]` and `[[clang::lifetimebound]]` are used together. (PR #108280)

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


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

Fixes #108272 

>From 0ee0f4660c8f9352c758ff80b0fa149bf9b5bd57 Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Wed, 11 Sep 2024 21:45:40 +0200
Subject: [PATCH] [clang] Don't emit bogus dangling diagnostics when
 ``[[gsl::Owner]]`` and `[[clang::lifetimebound]]` are used together.

---
 clang/docs/ReleaseNotes.rst                   |  2 ++
 clang/lib/Sema/CheckExprLifetime.cpp          |  3 +-
 .../Sema/warn-lifetime-analysis-nocfg.cpp     | 34 +++++++++++++++++++
 3 files changed, 38 insertions(+), 1 deletion(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 59ccdf1e15cd81..3a8f159492d2d3 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).
 
+- Don't emit bogus dangling diagnostics when ``[[gsl::Owner]]`` and `[[clang::lifetimebound]]` are used together (#GH108272).
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp
index c8e703036c132c..80343905bcaa4d 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -289,7 +289,8 @@ static bool isGSLOwner(QualType T) {
 
 static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
   if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee))
-    if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()))
+    if (isRecordWithAttr<PointerAttr>(Conv->getConversionType())
+        && Callee->getParent()->hasAttr<OwnerAttr>())
       return true;
   if (!isInStlNamespace(Callee->getParent()))
     return false;
diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
index 234e06f069074b..bc25c33bf9fed5 100644
--- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
+++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp
@@ -630,3 +630,37 @@ std::optional<std::string_view> test3(int i) {
 }
 
 } // namespace GH100526
+
+namespace GH108272 {
+template <typename T>
+struct [[gsl::Owner]] StatusOr {
+  const T &value() [[clang::lifetimebound]];
+};
+
+template <typename V>
+class Wrapper1 {
+ public:
+  operator V() const;
+  V value;
+};
+std::string_view test1() {
+  StatusOr<Wrapper1<std::string_view>> k;
+  // Be conservative in this case, as there is not enough information available
+  // to infer the lifetime relationship for the Wrapper1 type.
+  std::string_view good = StatusOr<Wrapper1<std::string_view>>().value();
+  return k.value();
+}
+
+template <typename V>
+class Wrapper2 {
+ public:
+  operator V() const [[clang::lifetimebound]];
+  V value;
+};
+std::string_view test2() {
+  StatusOr<Wrapper2<std::string_view>> k;
+  // We expect dangling issues as the conversion operator is lifetimebound。
+  std::string_view bad = StatusOr<Wrapper2<std::string_view>>().value(); // expected-warning {{temporary whose address is used as value of}}
+  return k.value(); // expected-warning {{address of stack memory associated}}
+}
+} // namespace GH108272



More information about the cfe-commits mailing list