[clang] [llvm] Implement pay-for-what-you-use warnings in LifetimeSafetyChecker (PR #221610)
Utkarsh Saxena via cfe-commits
cfe-commits at lists.llvm.org
Sun Sep 6 15:03:25 PDT 2026
https://github.com/usx95 created https://github.com/llvm/llvm-project/pull/221610
We split IsLifetimeSafetyEnabled into individual check functions in SemaLifetimeSafety.h:
- ShouldCheckSafety
- ShouldCheckNoescapeViolations
- ShouldCheckLifetimeboundViolations
- ShouldCheckMisplacedLifetimebound
- ShouldCheckInapplicableLifetimebound
- ShouldSuggestLifetimeAnnotations
These properties are stored in LifetimeSafetyOpts, which are then checked inside the Checker to avoid invoking expensive reporting functions mapping to diagnostics that are disabled.
>From f5101b2299031dd9a69bde61dc5afc9729d7515e Mon Sep 17 00:00:00 2001
From: Utkarsh Saxena <usx at google.com>
Date: Sun, 6 Sep 2026 21:19:22 +0000
Subject: [PATCH] Implement pay-for-what-you-use warnings in
LifetimeSafetyChecker
We split IsLifetimeSafetyEnabled into individual check functions
in SemaLifetimeSafety.h:
- ShouldCheckSafety
- ShouldCheckNoescapeViolations
- ShouldCheckLifetimeboundViolations
- ShouldCheckMisplacedLifetimebound
- ShouldCheckInapplicableLifetimebound
- ShouldSuggestLifetimeAnnotations
These properties are stored in LifetimeSafetyOpts, which are then checked
inside the Checker to avoid invoking expensive reporting functions mapping
to diagnostics that are disabled.
TAG=agy
CONV=a79c61c3-92c6-404e-83e3-3e3088f77c0e
---
.../Analyses/LifetimeSafety/LifetimeSafety.h | 5 +
clang/lib/Analysis/LifetimeSafety/Checker.cpp | 17 ++-
clang/lib/Sema/SemaLifetimeSafety.h | 99 +++++++++------
patch.diff | 14 +++
patch_checker.py | 24 ++++
patch_checker2.py | 43 +++++++
patch_sema.py | 116 ++++++++++++++++++
patch_sema2.py | 21 ++++
patch_sema3.py | 20 +++
9 files changed, 320 insertions(+), 39 deletions(-)
create mode 100644 patch.diff
create mode 100644 patch_checker.py
create mode 100644 patch_checker2.py
create mode 100644 patch_sema.py
create mode 100644 patch_sema2.py
create mode 100644 patch_sema3.py
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
index 101407e91aa65..68e84961010dd 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
@@ -41,6 +41,11 @@ struct LifetimeSafetyOpts {
/// Whether to suggest lifetime annotations.
bool SuggestAnnotations;
+
+ bool CheckNoescapeViolations;
+ bool CheckLifetimeboundViolations;
+ bool CheckMisplacedLifetimebound;
+ bool CheckInapplicableLifetimebound;
};
/// Enum to track functions visible across or within TU.
diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
index b136da486365a..a358215a295d1 100644
--- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
@@ -105,10 +105,14 @@ class LifetimeChecker {
checkAnnotations(OEF);
issuePendingWarnings();
suggestAnnotations();
- reportNoescapeViolations();
- reportLifetimeboundViolations();
- reportMisplacedLifetimebound();
- reportInapplicableLifetimebound();
+ if (LSOpts.CheckNoescapeViolations)
+ reportNoescapeViolations();
+ if (LSOpts.CheckLifetimeboundViolations)
+ reportLifetimeboundViolations();
+ if (LSOpts.CheckMisplacedLifetimebound)
+ reportMisplacedLifetimebound();
+ if (LSOpts.CheckInapplicableLifetimebound)
+ reportInapplicableLifetimebound();
// Annotation inference is currently guarded by a frontend flag. In the
// future, this might be replaced by a design that differentiates between
// explicit and inferred findings with separate warning groups.
@@ -254,6 +258,7 @@ class LifetimeChecker {
}
void issuePendingWarnings() {
+ llvm::TimeTraceScope TimeTrace("IssuePendingWarnings");
if (!SemaHelper)
return;
for (const auto &[LID, Warning] : FinalWarningsMap) {
@@ -436,6 +441,7 @@ class LifetimeChecker {
}
void reportNoescapeViolations() {
+ llvm::TimeTraceScope TimeTrace("ReportNoescapeViolations");
for (auto [PVD, EscapeTarget] : NoescapeWarningsMap) {
if (const auto *E = EscapeTarget.dyn_cast<const Expr *>())
SemaHelper->reportNoescapeViolation(PVD, E);
@@ -449,6 +455,7 @@ class LifetimeChecker {
}
void reportLifetimeboundViolations() {
+ llvm::TimeTraceScope TimeTrace("ReportLifetimeboundViolations");
if (!isa<FunctionDecl>(FD))
return;
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD);
@@ -471,6 +478,7 @@ class LifetimeChecker {
// Reports lifetimebound attributes that are placed on a function definition
// but not on the corresponding declaration.
void reportMisplacedLifetimebound() {
+ llvm::TimeTraceScope TimeTrace("ReportMisplacedLifetimebound");
const FunctionDecl *FDef = dyn_cast<FunctionDecl>(FD);
if (!FDef)
return;
@@ -501,6 +509,7 @@ class LifetimeChecker {
}
void reportInapplicableLifetimebound() {
+ llvm::TimeTraceScope TimeTrace("ReportInapplicableLifetimebound");
const auto *FDef = dyn_cast<FunctionDecl>(FD);
if (!FDef)
return;
diff --git a/clang/lib/Sema/SemaLifetimeSafety.h b/clang/lib/Sema/SemaLifetimeSafety.h
index d87c9003e83cf..ca941375a003f 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -25,28 +25,7 @@
namespace clang::lifetimes {
-inline bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D) {
- // TODO: Enable ObjectiveC later when we know it's stable enough.
- if (S.getLangOpts().ObjC)
- return false;
-
- // TODO: Default this flag to on in the future.
- if (!S.getLangOpts().CPlusPlus && !S.getLangOpts().EnableLifetimeSafetyInC)
- return false;
-
- // Translation-unit mode: whole-program analysis runs once on TU.
- // Individual function analysis is disabled when TU mode is enabled.
- if (S.getLangOpts().EnableLifetimeSafetyTUAnalysis)
- return isa<TranslationUnitDecl>(D);
-
- // Per-function mode: analysis runs on each function/method individually.
- // Skip TU-level calls when per-function mode is enabled.
- if (isa<TranslationUnitDecl>(D))
- return false;
-
- // Enable per-function mode via debug flag or specific diagnostics.
- if (S.getLangOpts().DebugRunLifetimeSafety)
- return true;
+inline bool ShouldCheckSafety(Sema &S, const Decl *D) {
DiagnosticsEngine &Diags = S.getDiagnostics();
constexpr unsigned DiagIDs[] = {
diag::warn_lifetime_safety_use_after_scope,
@@ -59,25 +38,40 @@ inline bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D) {
diag::warn_lifetime_safety_dangling_field_moved,
diag::warn_lifetime_safety_dangling_global,
diag::warn_lifetime_safety_dangling_global_moved,
- diag::warn_lifetime_safety_noescape_escapes,
- diag::warn_lifetime_safety_lifetimebound_violation,
- diag::warn_lifetime_safety_cross_tu_misplaced_lifetimebound,
- diag::warn_lifetime_safety_intra_tu_misplaced_lifetimebound,
diag::warn_lifetime_safety_invalidated_field,
- 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};
+ diag::warn_lifetime_safety_invalidated_global};
for (unsigned DiagID : DiagIDs)
if (!Diags.isIgnored(DiagID, D->getBeginLoc()))
return true;
return false;
}
+inline bool ShouldCheckNoescapeViolations(Sema &S, const Decl *D) {
+ return !S.getDiagnostics().isIgnored(
+ diag::warn_lifetime_safety_noescape_escapes, D->getBeginLoc());
+}
+
+inline bool ShouldCheckLifetimeboundViolations(Sema &S, const Decl *D) {
+ return !S.getDiagnostics().isIgnored(
+ diag::warn_lifetime_safety_lifetimebound_violation, D->getBeginLoc());
+}
+
+inline bool ShouldCheckMisplacedLifetimebound(Sema &S, const Decl *D) {
+ DiagnosticsEngine &Diags = S.getDiagnostics();
+ constexpr unsigned DiagIDs[] = {
+ diag::warn_lifetime_safety_cross_tu_misplaced_lifetimebound,
+ diag::warn_lifetime_safety_intra_tu_misplaced_lifetimebound};
+ for (unsigned DiagID : DiagIDs)
+ if (!Diags.isIgnored(DiagID, D->getBeginLoc()))
+ return true;
+ return false;
+}
+
+inline bool ShouldCheckInapplicableLifetimebound(Sema &S, const Decl *D) {
+ return !S.getDiagnostics().isIgnored(
+ diag::warn_lifetime_safety_inapplicable_lifetimebound, D->getBeginLoc());
+}
+
inline bool ShouldSuggestLifetimeAnnotations(Sema &S, const Decl *D) {
DiagnosticsEngine &Diags = S.getDiagnostics();
constexpr unsigned DiagIDs[] = {
@@ -93,13 +87,48 @@ inline bool ShouldSuggestLifetimeAnnotations(Sema &S, const Decl *D) {
return false;
}
+inline bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D) {
+ // TODO: Enable ObjectiveC later when we know it's stable enough.
+ if (S.getLangOpts().ObjC)
+ return false;
+
+ // TODO: Default this flag to on in the future.
+ if (!S.getLangOpts().CPlusPlus && !S.getLangOpts().EnableLifetimeSafetyInC)
+ return false;
+
+ // Translation-unit mode: whole-program analysis runs once on TU.
+ // Individual function analysis is disabled when TU mode is enabled.
+ if (S.getLangOpts().EnableLifetimeSafetyTUAnalysis)
+ return isa<TranslationUnitDecl>(D);
+
+ // Per-function mode: analysis runs on each function/method individually.
+ // Skip TU-level calls when per-function mode is enabled.
+ if (isa<TranslationUnitDecl>(D))
+ return false;
+
+ // Enable per-function mode via debug flag or specific diagnostics.
+ if (S.getLangOpts().DebugRunLifetimeSafety)
+ return true;
+
+ return ShouldCheckSafety(S, D) || ShouldCheckNoescapeViolations(S, D) ||
+ ShouldCheckLifetimeboundViolations(S, D) ||
+ ShouldCheckMisplacedLifetimebound(S, D) ||
+ ShouldCheckInapplicableLifetimebound(S, D) ||
+ ShouldSuggestLifetimeAnnotations(S, D);
+}
+
inline LifetimeSafetyOpts GetLifetimeSafetyOpts(Sema &S, const Decl *D) {
LifetimeSafetyOpts LSOpts;
LSOpts.MaxCFGBlocks = S.getLangOpts().LifetimeSafetyMaxCFGBlocks;
LSOpts.SuggestAnnotations = ShouldSuggestLifetimeAnnotations(S, D);
+ LSOpts.CheckNoescapeViolations = ShouldCheckNoescapeViolations(S, D);
+ LSOpts.CheckLifetimeboundViolations =
+ ShouldCheckLifetimeboundViolations(S, D);
+ LSOpts.CheckMisplacedLifetimebound = ShouldCheckMisplacedLifetimebound(S, D);
+ LSOpts.CheckInapplicableLifetimebound =
+ ShouldCheckInapplicableLifetimebound(S, D);
return LSOpts;
}
-
class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
public:
diff --git a/patch.diff b/patch.diff
new file mode 100644
index 0000000000000..665139146f600
--- /dev/null
+++ b/patch.diff
@@ -0,0 +1,14 @@
+--- clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
++++ clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
+@@ -41,6 +41,11 @@ struct LifetimeSafetyOpts {
+
+ /// Whether to suggest lifetime annotations.
+ bool SuggestAnnotations;
++
++ bool CheckNoescapeViolations;
++ bool CheckLifetimeboundViolations;
++ bool CheckMisplacedLifetimebound;
++ bool CheckInapplicableLifetimebound;
+ };
+
+ /// Enum to track functions visible across or within TU.
diff --git a/patch_checker.py b/patch_checker.py
new file mode 100644
index 0000000000000..241b01cd220d0
--- /dev/null
+++ b/patch_checker.py
@@ -0,0 +1,24 @@
+import re
+
+with open('clang/lib/Analysis/LifetimeSafety/Checker.cpp', 'r') as f:
+ orig = f.read()
+
+# Replace the calls in `check()` function
+orig = orig.replace(""" issuePendingWarnings();
+ suggestAnnotations();
+ reportNoescapeViolations();
+ reportLifetimeboundViolations();
+ reportMisplacedLifetimebound();
+ reportInapplicableLifetimebound();""", """ issuePendingWarnings();
+ suggestAnnotations();
+ if (LSOpts.CheckNoescapeViolations)
+ reportNoescapeViolations();
+ if (LSOpts.CheckLifetimeboundViolations)
+ reportLifetimeboundViolations();
+ if (LSOpts.CheckMisplacedLifetimebound)
+ reportMisplacedLifetimebound();
+ if (LSOpts.CheckInapplicableLifetimebound)
+ reportInapplicableLifetimebound();""")
+
+with open('clang/lib/Analysis/LifetimeSafety/Checker.cpp', 'w') as f:
+ f.write(orig)
diff --git a/patch_checker2.py b/patch_checker2.py
new file mode 100644
index 0000000000000..a5c0265739093
--- /dev/null
+++ b/patch_checker2.py
@@ -0,0 +1,43 @@
+import re
+
+with open('clang/lib/Analysis/LifetimeSafety/Checker.cpp', 'r') as f:
+ orig = f.read()
+
+# Add TimeTraceScope to reportNoescapeViolations
+orig = re.sub(
+ r'(void reportNoescapeViolations\(\) {\n)',
+ r'\1 llvm::TimeTraceScope TimeTrace("ReportNoescapeViolations");\n',
+ orig
+)
+
+# Add TimeTraceScope to reportLifetimeboundViolations
+orig = re.sub(
+ r'(void reportLifetimeboundViolations\(\) {\n)',
+ r'\1 llvm::TimeTraceScope TimeTrace("ReportLifetimeboundViolations");\n',
+ orig
+)
+
+# Add TimeTraceScope to reportMisplacedLifetimebound
+orig = re.sub(
+ r'(void reportMisplacedLifetimebound\(\) {\n)',
+ r'\1 llvm::TimeTraceScope TimeTrace("ReportMisplacedLifetimebound");\n',
+ orig
+)
+
+# Add TimeTraceScope to reportInapplicableLifetimebound
+orig = re.sub(
+ r'(void reportInapplicableLifetimebound\(\) {\n)',
+ r'\1 llvm::TimeTraceScope TimeTrace("ReportInapplicableLifetimebound");\n',
+ orig
+)
+
+# Might as well do issuePendingWarnings
+orig = re.sub(
+ r'(void issuePendingWarnings\(\) {\n)',
+ r'\1 llvm::TimeTraceScope TimeTrace("IssuePendingWarnings");\n',
+ orig
+)
+
+
+with open('clang/lib/Analysis/LifetimeSafety/Checker.cpp', 'w') as f:
+ f.write(orig)
diff --git a/patch_sema.py b/patch_sema.py
new file mode 100644
index 0000000000000..1bc743da23dcf
--- /dev/null
+++ b/patch_sema.py
@@ -0,0 +1,116 @@
+import re
+
+with open('clang/lib/Sema/SemaLifetimeSafety.h', 'r') as f:
+ orig = f.read()
+
+replacement = """
+inline bool ShouldCheckSafety(Sema &S, const Decl *D) {
+ DiagnosticsEngine &Diags = S.getDiagnostics();
+ constexpr unsigned DiagIDs[] = {
+ diag::warn_lifetime_safety_use_after_scope,
+ diag::warn_lifetime_safety_use_after_scope_moved,
+ diag::warn_lifetime_safety_use_after_free,
+ diag::warn_lifetime_safety_return_stack_addr,
+ diag::warn_lifetime_safety_return_stack_addr_moved,
+ diag::warn_lifetime_safety_invalidation,
+ diag::warn_lifetime_safety_dangling_field,
+ diag::warn_lifetime_safety_dangling_field_moved,
+ diag::warn_lifetime_safety_dangling_global,
+ diag::warn_lifetime_safety_dangling_global_moved,
+ diag::warn_lifetime_safety_invalidated_field,
+ diag::warn_lifetime_safety_invalidated_global};
+ for (unsigned DiagID : DiagIDs)
+ if (!Diags.isIgnored(DiagID, D->getBeginLoc()))
+ return true;
+ return false;
+}
+
+inline bool ShouldCheckNoescapeViolations(Sema &S, const Decl *D) {
+ return !S.getDiagnostics().isIgnored(diag::warn_lifetime_safety_noescape_escapes, D->getBeginLoc());
+}
+
+inline bool ShouldCheckLifetimeboundViolations(Sema &S, const Decl *D) {
+ return !S.getDiagnostics().isIgnored(diag::warn_lifetime_safety_lifetimebound_violation, D->getBeginLoc());
+}
+
+inline bool ShouldCheckMisplacedLifetimebound(Sema &S, const Decl *D) {
+ DiagnosticsEngine &Diags = S.getDiagnostics();
+ constexpr unsigned DiagIDs[] = {
+ diag::warn_lifetime_safety_cross_tu_misplaced_lifetimebound,
+ diag::warn_lifetime_safety_intra_tu_misplaced_lifetimebound};
+ for (unsigned DiagID : DiagIDs)
+ if (!Diags.isIgnored(DiagID, D->getBeginLoc()))
+ return true;
+ return false;
+}
+
+inline bool ShouldCheckInapplicableLifetimebound(Sema &S, const Decl *D) {
+ return !S.getDiagnostics().isIgnored(diag::warn_lifetime_safety_inapplicable_lifetimebound, D->getBeginLoc());
+}
+
+inline bool ShouldSuggestLifetimeAnnotations(Sema &S, const Decl *D) {
+ DiagnosticsEngine &Diags = S.getDiagnostics();
+ 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)
+ if (!Diags.isIgnored(DiagID, D->getBeginLoc()))
+ return true;
+ return false;
+}
+
+inline bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D) {
+ // TODO: Enable ObjectiveC later when we know it's stable enough.
+ if (S.getLangOpts().ObjC)
+ return false;
+
+ // TODO: Default this flag to on in the future.
+ if (!S.getLangOpts().CPlusPlus && !S.getLangOpts().EnableLifetimeSafetyInC)
+ return false;
+
+ // Translation-unit mode: whole-program analysis runs once on TU.
+ // Individual function analysis is disabled when TU mode is enabled.
+ if (S.getLangOpts().EnableLifetimeSafetyTUAnalysis)
+ return isa<TranslationUnitDecl>(D);
+
+ // Per-function mode: analysis runs on each function/method individually.
+ // Skip TU-level calls when per-function mode is enabled.
+ if (isa<TranslationUnitDecl>(D))
+ return false;
+
+ // Enable per-function mode via debug flag or specific diagnostics.
+ if (S.getLangOpts().DebugRunLifetimeSafety)
+ return true;
+
+ return ShouldCheckSafety(S, D) ||
+ ShouldCheckNoescapeViolations(S, D) ||
+ ShouldCheckLifetimeboundViolations(S, D) ||
+ ShouldCheckMisplacedLifetimebound(S, D) ||
+ ShouldCheckInapplicableLifetimebound(S, D) ||
+ ShouldSuggestLifetimeAnnotations(S, D);
+}
+
+inline LifetimeSafetyOpts GetLifetimeSafetyOpts(Sema &S, const Decl *D) {
+ LifetimeSafetyOpts LSOpts;
+ LSOpts.MaxCFGBlocks = S.getLangOpts().LifetimeSafetyMaxCFGBlocks;
+ LSOpts.SuggestAnnotations = ShouldSuggestLifetimeAnnotations(S, D);
+ LSOpts.CheckNoescapeViolations = ShouldCheckNoescapeViolations(S, D);
+ LSOpts.CheckLifetimeboundViolations = ShouldCheckLifetimeboundViolations(S, D);
+ LSOpts.CheckMisplacedLifetimebound = ShouldCheckMisplacedLifetimebound(S, D);
+ LSOpts.CheckInapplicableLifetimebound = ShouldCheckInapplicableLifetimebound(S, D);
+ return LSOpts;
+}
+"""
+
+start_idx = orig.find('inline bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D) {')
+end_idx = orig.find('class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {')
+
+new_content = orig[:start_idx] + replacement + orig[end_idx:]
+
+with open('clang/lib/Sema/SemaLifetimeSafety.h', 'w') as f:
+ f.write(new_content)
+
diff --git a/patch_sema2.py b/patch_sema2.py
new file mode 100644
index 0000000000000..424c95372d336
--- /dev/null
+++ b/patch_sema2.py
@@ -0,0 +1,21 @@
+import re
+
+with open('clang/lib/Sema/SemaLifetimeSafety.h', 'r') as f:
+ orig = f.read()
+
+replacement = """inline LifetimeSafetyOpts GetLifetimeSafetyOpts(Sema &S, const Decl *D) {
+ LifetimeSafetyOpts LSOpts;
+ LSOpts.MaxCFGBlocks = S.getLangOpts().LifetimeSafetyMaxCFGBlocks;
+ bool Debug = S.getLangOpts().DebugRunLifetimeSafety;
+ LSOpts.SuggestAnnotations = Debug || ShouldSuggestLifetimeAnnotations(S, D);
+ LSOpts.CheckNoescapeViolations = Debug || ShouldCheckNoescapeViolations(S, D);
+ LSOpts.CheckLifetimeboundViolations = Debug || ShouldCheckLifetimeboundViolations(S, D);
+ LSOpts.CheckMisplacedLifetimebound = Debug || ShouldCheckMisplacedLifetimebound(S, D);
+ LSOpts.CheckInapplicableLifetimebound = Debug || ShouldCheckInapplicableLifetimebound(S, D);
+ return LSOpts;
+}"""
+
+orig = re.sub(r'inline LifetimeSafetyOpts GetLifetimeSafetyOpts\(Sema &S, const Decl \*D\) \{.*return LSOpts;\n}', replacement, orig, flags=re.DOTALL)
+
+with open('clang/lib/Sema/SemaLifetimeSafety.h', 'w') as f:
+ f.write(orig)
diff --git a/patch_sema3.py b/patch_sema3.py
new file mode 100644
index 0000000000000..e054cd8a0578e
--- /dev/null
+++ b/patch_sema3.py
@@ -0,0 +1,20 @@
+import re
+
+with open('clang/lib/Sema/SemaLifetimeSafety.h', 'r') as f:
+ orig = f.read()
+
+replacement = """inline LifetimeSafetyOpts GetLifetimeSafetyOpts(Sema &S, const Decl *D) {
+ LifetimeSafetyOpts LSOpts;
+ LSOpts.MaxCFGBlocks = S.getLangOpts().LifetimeSafetyMaxCFGBlocks;
+ LSOpts.SuggestAnnotations = ShouldSuggestLifetimeAnnotations(S, D);
+ LSOpts.CheckNoescapeViolations = ShouldCheckNoescapeViolations(S, D);
+ LSOpts.CheckLifetimeboundViolations = ShouldCheckLifetimeboundViolations(S, D);
+ LSOpts.CheckMisplacedLifetimebound = ShouldCheckMisplacedLifetimebound(S, D);
+ LSOpts.CheckInapplicableLifetimebound = ShouldCheckInapplicableLifetimebound(S, D);
+ return LSOpts;
+}"""
+
+orig = re.sub(r'inline LifetimeSafetyOpts GetLifetimeSafetyOpts\(Sema &S, const Decl \*D\) \{.*return LSOpts;\n}', replacement, orig, flags=re.DOTALL)
+
+with open('clang/lib/Sema/SemaLifetimeSafety.h', 'w') as f:
+ f.write(orig)
More information about the cfe-commits
mailing list