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
