[clang] ctor-suggestions-separate (PR #206254)

Utkarsh Saxena via cfe-commits cfe-commits at lists.llvm.org
Sat Jun 27 07:27:52 PDT 2026


https://github.com/usx95 updated https://github.com/llvm/llvm-project/pull/206254

>From ff93d2d66f7cdcab049cd7051eb1d248c202818b Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Sat, 27 Jun 2026 14:15:12 +0000
Subject: [PATCH 1/3] ctor-suggestions-separate

---
 clang/include/clang/Basic/DiagnosticGroups.td   | 11 +++++++++--
 .../include/clang/Basic/DiagnosticSemaKinds.td  | 12 ++++++++++++
 clang/lib/Sema/SemaLifetimeSafety.h             | 17 +++++++++++++----
 .../LifetimeSafety/annotation-suggestions.cpp   | 14 +++++++-------
 4 files changed, 41 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 6418ab4757a0c..72c3da285b47f 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -673,10 +673,17 @@ Warnings to detect use-after-free and related temporal safety bugs based on life
   }];
 }
 
+def LifetimeSafetyCrossTUSuggestionsConstructors
+    : DiagGroup<"lifetime-safety-cross-tu-suggestions-constructors">;
+def LifetimeSafetyIntraTUSuggestionsConstructors
+    : DiagGroup<"lifetime-safety-intra-tu-suggestions-constructors">;
+
 def LifetimeSafetyCrossTUSuggestions
-    : DiagGroup<"lifetime-safety-cross-tu-suggestions">;
+    : DiagGroup<"lifetime-safety-cross-tu-suggestions",
+                [LifetimeSafetyCrossTUSuggestionsConstructors]>;
 def LifetimeSafetyIntraTUSuggestions
-    : DiagGroup<"lifetime-safety-intra-tu-suggestions">;
+    : DiagGroup<"lifetime-safety-intra-tu-suggestions",
+                [LifetimeSafetyIntraTUSuggestionsConstructors]>;
 def LifetimeSafetySuggestions
     : DiagGroup<"lifetime-safety-suggestions",
                 [LifetimeSafetyCrossTUSuggestions,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7e20630708312..0feb4df38a283 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11082,6 +11082,18 @@ def warn_lifetime_safety_cross_tu_param_suggestion
       InGroup<LifetimeSafetyCrossTUSuggestions>,
       DefaultIgnore;
 
+def warn_lifetime_safety_intra_tu_ctor_param_suggestion
+    : Warning<"parameter in intra-TU constructor should be marked "
+              "[[clang::lifetimebound]]">,
+      InGroup<LifetimeSafetyIntraTUSuggestionsConstructors>,
+      DefaultIgnore;
+
+def warn_lifetime_safety_cross_tu_ctor_param_suggestion
+    : Warning<"parameter in cross-TU constructor should be marked "
+              "[[clang::lifetimebound]]">,
+      InGroup<LifetimeSafetyCrossTUSuggestionsConstructors>,
+      DefaultIgnore;
+
 def warn_lifetime_safety_intra_tu_this_suggestion
     : Warning<"implicit this in intra-TU function should be marked "
               "[[clang::lifetimebound]]">,
diff --git a/clang/lib/Sema/SemaLifetimeSafety.h b/clang/lib/Sema/SemaLifetimeSafety.h
index a3d546792fe41..3b9ea9eafbec5 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -67,6 +67,8 @@ inline bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D) {
       diag::warn_lifetime_safety_invalidated_global,
       diag::warn_lifetime_safety_cross_tu_param_suggestion,
       diag::warn_lifetime_safety_intra_tu_param_suggestion,
+      diag::warn_lifetime_safety_cross_tu_ctor_param_suggestion,
+      diag::warn_lifetime_safety_intra_tu_ctor_param_suggestion,
       diag::warn_lifetime_safety_cross_tu_this_suggestion,
       diag::warn_lifetime_safety_intra_tu_this_suggestion,
       diag::warn_lifetime_safety_inapplicable_lifetimebound};
@@ -81,6 +83,8 @@ inline bool ShouldSuggestLifetimeAnnotations(Sema &S, const Decl *D) {
   constexpr unsigned DiagIDs[] = {
       diag::warn_lifetime_safety_intra_tu_param_suggestion,
       diag::warn_lifetime_safety_cross_tu_param_suggestion,
+      diag::warn_lifetime_safety_intra_tu_ctor_param_suggestion,
+      diag::warn_lifetime_safety_cross_tu_ctor_param_suggestion,
       diag::warn_lifetime_safety_intra_tu_this_suggestion,
       diag::warn_lifetime_safety_cross_tu_this_suggestion};
   for (unsigned DiagID : DiagIDs)
@@ -280,10 +284,15 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
   void suggestLifetimeboundToParmVar(WarningScope Scope,
                                      const ParmVarDecl *ParmToAnnotate,
                                      EscapingTarget Target) override {
-    unsigned DiagID =
-        (Scope == WarningScope::CrossTU)
-            ? diag::warn_lifetime_safety_cross_tu_param_suggestion
-            : diag::warn_lifetime_safety_intra_tu_param_suggestion;
+    unsigned DiagID;
+    if (isa<CXXConstructorDecl>(ParmToAnnotate->getDeclContext()))
+      DiagID = (Scope == WarningScope::CrossTU)
+                   ? diag::warn_lifetime_safety_cross_tu_ctor_param_suggestion
+                   : diag::warn_lifetime_safety_intra_tu_ctor_param_suggestion;
+    else
+      DiagID = (Scope == WarningScope::CrossTU)
+                   ? diag::warn_lifetime_safety_cross_tu_param_suggestion
+                   : diag::warn_lifetime_safety_intra_tu_param_suggestion;
 
     auto [InsertionPoint, FixItText] = getLifetimeBoundFixIt(ParmToAnnotate);
 
diff --git a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
index 98c528516b8e7..56ed4a6dc7106 100644
--- a/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
+++ b/clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp
@@ -522,7 +522,7 @@ S forward(const MyObj &obj) { // expected-warning {{parameter in intra-TU functi
 namespace capturing_constructor {
 struct CaptureRefToView {
   View v; // expected-note {{escapes to this field}}
-  CaptureRefToView(const MyObj& obj) : v(obj) {} // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+  CaptureRefToView(const MyObj& obj) : v(obj) {} // expected-warning {{parameter in intra-TU constructor should be marked [[clang::lifetimebound]]}}
 };
 
 CaptureRefToView test_ref_to_view() {
@@ -533,7 +533,7 @@ CaptureRefToView test_ref_to_view() {
 
 struct CaptureRefToPtr {
   const MyObj* p; // expected-note {{escapes to this field}}
-  CaptureRefToPtr(const MyObj& obj) : p(&obj) {} // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+  CaptureRefToPtr(const MyObj& obj) : p(&obj) {} // expected-warning {{parameter in intra-TU constructor should be marked [[clang::lifetimebound]]}}
 };
 
 CaptureRefToPtr test_ref_to_ptr() {
@@ -544,7 +544,7 @@ CaptureRefToPtr test_ref_to_ptr() {
 
 struct CaptureViewToView {
   View v; // expected-note {{escapes to this field}}
-  CaptureViewToView(View v_param) : v(v_param) {} // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+  CaptureViewToView(View v_param) : v(v_param) {} // expected-warning {{parameter in intra-TU constructor should be marked [[clang::lifetimebound]]}}
 };
 
 CaptureViewToView test_view_to_view() {
@@ -556,7 +556,7 @@ CaptureViewToView test_view_to_view() {
 
 struct CapturePtrToPtr {
   const MyObj* p; // expected-note {{escapes to this field}}
-  CapturePtrToPtr(const MyObj* p_param) : p(p_param) {} // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+  CapturePtrToPtr(const MyObj* p_param) : p(p_param) {} // expected-warning {{parameter in intra-TU constructor should be marked [[clang::lifetimebound]]}}
 };
 
 CapturePtrToPtr test_ptr_to_ptr() {
@@ -567,7 +567,7 @@ CapturePtrToPtr test_ptr_to_ptr() {
 
 struct CaptureRefToRef {
   const MyObj& r; // expected-note {{escapes to this field}}
-  CaptureRefToRef(const MyObj& obj) : r(obj) {} // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+  CaptureRefToRef(const MyObj& obj) : r(obj) {} // expected-warning {{parameter in intra-TU constructor should be marked [[clang::lifetimebound]]}}
 };
 
 CaptureRefToRef test_ref_to_ref() {
@@ -580,7 +580,7 @@ struct BaseWithView {
   View v; // expected-note {{escapes to this field}}
 };
 struct CaptureRefToBaseView : BaseWithView {
-  CaptureRefToBaseView(const MyObj& obj) { // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+  CaptureRefToBaseView(const MyObj& obj) { // expected-warning {{parameter in intra-TU constructor should be marked [[clang::lifetimebound]]}}
     v = obj;
   }
 };
@@ -654,7 +654,7 @@ struct LifetimeBoundCtor {
 
 struct HasCtorField {
   LifetimeBoundCtor* field;                                             // expected-note {{escapes to this field}}
-  HasCtorField(const MyObj& obj) : field(new LifetimeBoundCtor(obj)) {} // expected-warning {{parameter in intra-TU function should be marked [[clang::lifetimebound]]}}
+  HasCtorField(const MyObj& obj) : field(new LifetimeBoundCtor(obj)) {} // expected-warning {{parameter in intra-TU constructor should be marked [[clang::lifetimebound]]}}
 };
 
 HasCtorField test_dangling_field_ctor() {

>From 0352e9c273b6fa57c9c008e63e43c912e1bf2c72 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Sat, 27 Jun 2026 14:17:12 +0000
Subject: [PATCH 2/3] docs

---
 clang/docs/LifetimeSafety.rst | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang/docs/LifetimeSafety.rst b/clang/docs/LifetimeSafety.rst
index be9b32f8d4b2d..75cacd28c3b47 100644
--- a/clang/docs/LifetimeSafety.rst
+++ b/clang/docs/LifetimeSafety.rst
@@ -524,7 +524,9 @@ enables only the high-confidence subset of these checks.
 *   ``-Wlifetime-safety-suggestions``: Enables suggestions to add ``[[clang::lifetimebound]]`` to function parameters and ``this`` parameters.
 
   * ``-Wlifetime-safety-intra-tu-suggestions``: Suggestions for functions local to the translation unit.
+    * ``-Wlifetime-safety-intra-tu-suggestions-constructors``: Suggestions for constructors local to the translation unit.
   * ``-Wlifetime-safety-cross-tu-suggestions``: Suggestions for functions visible across translation units (e.g., in headers).
+    * ``-Wlifetime-safety-cross-tu-suggestions-constructors``: Suggestions for constructors visible across translation units.
 
 * ``-Wlifetime-safety-validations``: Enables checks that validate existing lifetime annotations.
 

>From e19a986492c47923e8e03c324b4c2198e9eb4ab1 Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Sat, 27 Jun 2026 14:26:20 +0000
Subject: [PATCH 3/3] rename

---
 clang/docs/LifetimeSafety.rst                    |  4 ++--
 clang/include/clang/Basic/DiagnosticGroups.td    | 12 ++++++------
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  4 ++--
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/clang/docs/LifetimeSafety.rst b/clang/docs/LifetimeSafety.rst
index 75cacd28c3b47..ec97a795e5670 100644
--- a/clang/docs/LifetimeSafety.rst
+++ b/clang/docs/LifetimeSafety.rst
@@ -524,9 +524,9 @@ enables only the high-confidence subset of these checks.
 *   ``-Wlifetime-safety-suggestions``: Enables suggestions to add ``[[clang::lifetimebound]]`` to function parameters and ``this`` parameters.
 
   * ``-Wlifetime-safety-intra-tu-suggestions``: Suggestions for functions local to the translation unit.
-    * ``-Wlifetime-safety-intra-tu-suggestions-constructors``: Suggestions for constructors local to the translation unit.
+    * ``-Wlifetime-safety-intra-tu-constructor-suggestions``: Suggestions for constructors local to the translation unit.
   * ``-Wlifetime-safety-cross-tu-suggestions``: Suggestions for functions visible across translation units (e.g., in headers).
-    * ``-Wlifetime-safety-cross-tu-suggestions-constructors``: Suggestions for constructors visible across translation units.
+    * ``-Wlifetime-safety-cross-tu-constructor-suggestions``: Suggestions for constructors visible across translation units.
 
 * ``-Wlifetime-safety-validations``: Enables checks that validate existing lifetime annotations.
 
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 72c3da285b47f..1c9d021317289 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -673,17 +673,17 @@ Warnings to detect use-after-free and related temporal safety bugs based on life
   }];
 }
 
-def LifetimeSafetyCrossTUSuggestionsConstructors
-    : DiagGroup<"lifetime-safety-cross-tu-suggestions-constructors">;
-def LifetimeSafetyIntraTUSuggestionsConstructors
-    : DiagGroup<"lifetime-safety-intra-tu-suggestions-constructors">;
+def LifetimeSafetyCrossTUConstructorSuggestions
+    : DiagGroup<"lifetime-safety-cross-tu-constructor-suggestions">;
+def LifetimeSafetyIntraTUConstructorSuggestions
+    : DiagGroup<"lifetime-safety-intra-tu-constructor-suggestions">;
 
 def LifetimeSafetyCrossTUSuggestions
     : DiagGroup<"lifetime-safety-cross-tu-suggestions",
-                [LifetimeSafetyCrossTUSuggestionsConstructors]>;
+                [LifetimeSafetyCrossTUConstructorSuggestions]>;
 def LifetimeSafetyIntraTUSuggestions
     : DiagGroup<"lifetime-safety-intra-tu-suggestions",
-                [LifetimeSafetyIntraTUSuggestionsConstructors]>;
+                [LifetimeSafetyIntraTUConstructorSuggestions]>;
 def LifetimeSafetySuggestions
     : DiagGroup<"lifetime-safety-suggestions",
                 [LifetimeSafetyCrossTUSuggestions,
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0feb4df38a283..dae400d6d16b4 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11085,13 +11085,13 @@ def warn_lifetime_safety_cross_tu_param_suggestion
 def warn_lifetime_safety_intra_tu_ctor_param_suggestion
     : Warning<"parameter in intra-TU constructor should be marked "
               "[[clang::lifetimebound]]">,
-      InGroup<LifetimeSafetyIntraTUSuggestionsConstructors>,
+      InGroup<LifetimeSafetyIntraTUConstructorSuggestions>,
       DefaultIgnore;
 
 def warn_lifetime_safety_cross_tu_ctor_param_suggestion
     : Warning<"parameter in cross-TU constructor should be marked "
               "[[clang::lifetimebound]]">,
-      InGroup<LifetimeSafetyCrossTUSuggestionsConstructors>,
+      InGroup<LifetimeSafetyCrossTUConstructorSuggestions>,
       DefaultIgnore;
 
 def warn_lifetime_safety_intra_tu_this_suggestion



More information about the cfe-commits mailing list