[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