[clang] [clang] Lifetimebound in assignment operator should work for non-gsl annotated types. (PR #113180)

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 21 08:20:40 PDT 2024


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

This issue is identified during the discussion of [this comment](https://github.com/llvm/llvm-project/issues/112234#issuecomment-2426102198).

There will be no release note for this fix as it is a follow-up to [PR #106997](https://github.com/llvm/llvm-project/pull/106997).

>From f6a4945ea02a34deff3e9cbf7f6af87f96a26c4e Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Mon, 21 Oct 2024 17:04:35 +0200
Subject: [PATCH] [clang] Lifetimebound in assignment operator should work for
 non-gsl annotated types.

---
 .../clang/Basic/DiagnosticSemaKinds.td        |  2 +-
 clang/lib/Sema/CheckExprLifetime.cpp          | 22 +++++++++++++------
 clang/test/SemaCXX/attr-lifetimebound.cpp     |  6 ++---
 3 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 883db838ca0147..ca25d49aec4501 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10188,7 +10188,7 @@ def warn_new_dangling_initializer_list : Warning<
   "will be destroyed at the end of the full-expression">,
   InGroup<DanglingInitializerList>;
 def warn_dangling_pointer_assignment : Warning<
-   "object backing the pointer %0 "
+   "object backing the %select{|pointer }0%1 "
    "will be destroyed at the end of the full-expression">,
    InGroup<DanglingAssignment>;
 
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp
index 8caeae5fcf9f8e..aa0a2e223e708f 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -1206,11 +1206,13 @@ static void checkExprLifetimeImpl(Sema &SemaRef,
       assert(shouldLifetimeExtendThroughPath(Path) ==
                  PathLifetimeKind::NoExtend &&
              "No lifetime extension for assignments");
-      SemaRef.Diag(DiagLoc,
-                   IsGslPtrValueFromGslTempOwner
-                       ? diag::warn_dangling_lifetime_pointer_assignment
-                       : diag::warn_dangling_pointer_assignment)
-          << AEntity->LHS << DiagRange;
+      if (IsGslPtrValueFromGslTempOwner)
+        SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer_assignment)
+            << AEntity->LHS << DiagRange;
+      else
+        SemaRef.Diag(DiagLoc, diag::warn_dangling_pointer_assignment)
+            << AEntity->LHS->getType()->isPointerType() << AEntity->LHS
+            << DiagRange;
       return false;
     }
     case LK_MemInitializer: {
@@ -1412,8 +1414,14 @@ static void checkExprLifetimeImpl(Sema &SemaRef,
   };
 
   llvm::SmallVector<IndirectLocalPathEntry, 8> Path;
-  if (LK == LK_Assignment && shouldRunGSLAssignmentAnalysis(SemaRef, *AEntity))
-    Path.push_back({IndirectLocalPathEntry::GslPointerAssignment, Init});
+  if (LK == LK_Assignment &&
+      shouldRunGSLAssignmentAnalysis(SemaRef, *AEntity)) {
+    Path.push_back(
+        {isAssignmentOperatorLifetimeBound(AEntity->AssignmentOperator)
+             ? IndirectLocalPathEntry::LifetimeBoundCall
+             : IndirectLocalPathEntry::GslPointerAssignment,
+         Init});
+  }
 
   if (Init->isGLValue())
     visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding,
diff --git a/clang/test/SemaCXX/attr-lifetimebound.cpp b/clang/test/SemaCXX/attr-lifetimebound.cpp
index d04bbb32433fb5..990e55ce057116 100644
--- a/clang/test/SemaCXX/attr-lifetimebound.cpp
+++ b/clang/test/SemaCXX/attr-lifetimebound.cpp
@@ -330,8 +330,8 @@ struct StatusOr {
 };
 
 void test(StatusOr<FooView> foo1, StatusOr<NonAnnotatedFooView> foo2) {
-  foo1 = Foo(); // expected-warning {{object backing the pointer foo1 will be destroyed at the end}}
-  // No warning on non-gsl annotated types.
-  foo2 = NonAnnotatedFoo();
+  foo1 = Foo(); // expected-warning {{object backing the foo1 will be destroyed at the end}}
+  // This warning is triggered by the lifetimebound annotation, regardless of whether the class type is annotated with GSL.
+  foo2 = NonAnnotatedFoo(); // expected-warning {{object backing the foo2 will be destroyed at the end}}
 }
 } // namespace GH106372



More information about the cfe-commits mailing list