Author: Utkarsh Saxena
Date: 2026-06-29T11:26:05+02:00
New Revision: 9c1161cd0d1bf53aeab8fe558b7b7c026f1f2a73

URL: 
https://github.com/llvm/llvm-project/commit/9c1161cd0d1bf53aeab8fe558b7b7c026f1f2a73
DIFF: 
https://github.com/llvm/llvm-project/commit/9c1161cd0d1bf53aeab8fe558b7b7c026f1f2a73.diff

LOG: [LifetimeSafety] Add separate diagnostic groups for constructor annotation 
suggestions (#206254)

Reason:
* Better selective enablement.
* In experience, constructor annotations are the most useful and
improves detection by manifolds.

Added: 
    

Modified: 
    clang/docs/LifetimeSafety.rst
    clang/include/clang/Basic/DiagnosticGroups.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaLifetimeSafety.h
    clang/test/Sema/LifetimeSafety/annotation-suggestions.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/LifetimeSafety.rst b/clang/docs/LifetimeSafety.rst
index be9b32f8d4b2d..ec97a795e5670 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-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-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 6418ab4757a0c..1c9d021317289 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 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">;
+    : DiagGroup<"lifetime-safety-cross-tu-suggestions",
+                [LifetimeSafetyCrossTUConstructorSuggestions]>;
 def LifetimeSafetyIntraTUSuggestions
-    : DiagGroup<"lifetime-safety-intra-tu-suggestions">;
+    : DiagGroup<"lifetime-safety-intra-tu-suggestions",
+                [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 6b2d78881d4e2..bf70b93acf0eb 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11085,6 +11085,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<LifetimeSafetyIntraTUConstructorSuggestions>,
+      DefaultIgnore;
+
+def warn_lifetime_safety_cross_tu_ctor_param_suggestion
+    : Warning<"parameter in cross-TU constructor should be marked "
+              "[[clang::lifetimebound]]">,
+      InGroup<LifetimeSafetyCrossTUConstructorSuggestions>,
+      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() {


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to