[clang] 75a2567 - [LifetimeSafety] Gate annotation suggestions behind `SuggestAnnotations` opt (#205764)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 25 05:58:33 PDT 2026
Author: Utkarsh Saxena
Date: 2026-06-25T14:58:28+02:00
New Revision: 75a256727cc5977775bc85f30fea9767f8e53b65
URL: https://github.com/llvm/llvm-project/commit/75a256727cc5977775bc85f30fea9767f8e53b65
DIFF: https://github.com/llvm/llvm-project/commit/75a256727cc5977775bc85f30fea9767f8e53b65.diff
LOG: [LifetimeSafety] Gate annotation suggestions behind `SuggestAnnotations` opt (#205764)
Annotations suggestions expectedly fire very often and they have
recently shown significant regressions after the
https://github.com/llvm/llvm-project/pull/204045. This now gates the
suggestions behind a dedicated `SuggestAnnotations` option, preventing
unnecessary work when the relevant diagnostics are disabled.
Added:
Modified:
clang/include/clang/Analysis/Analyses/LifetimeSafety/Checker.h
clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
clang/lib/Analysis/LifetimeSafety/Checker.cpp
clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
clang/lib/Sema/AnalysisBasedWarnings.cpp
clang/lib/Sema/SemaLifetimeSafety.h
clang/test/Sema/LifetimeSafety/safety.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Checker.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Checker.h
index 1ad3f9da61f60..99ad816311e74 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/Checker.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/Checker.h
@@ -29,7 +29,8 @@ void runLifetimeChecker(const LoanPropagationAnalysis &LoanPropagation,
const MovedLoansAnalysis &MovedLoans,
const LiveOriginsAnalysis &LiveOrigins,
FactManager &FactMgr, AnalysisDeclContext &ADC,
- LifetimeSafetySemaHelper *SemaHelper);
+ LifetimeSafetySemaHelper *SemaHelper,
+ const LifetimeSafetyOpts &LSOpts);
} // namespace clang::lifetimes::internal
diff --git a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
index 28886b826f72f..80a23f18baebd 100644
--- a/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
+++ b/clang/include/clang/Analysis/Analyses/LifetimeSafety/LifetimeSafety.h
@@ -38,6 +38,9 @@ struct LifetimeSafetyOpts {
/// Maximum number of CFG blocks to analyze. Functions with larger CFGs will
/// be skipped.
size_t MaxCFGBlocks;
+
+ /// Whether to suggest lifetime annotations.
+ bool SuggestAnnotations;
};
/// Enum to track functions visible across or within TU.
@@ -157,6 +160,7 @@ class LifetimeSafetySemaHelper {
/// The main entry point for the analysis.
void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC,
LifetimeSafetySemaHelper *SemaHelper,
+ const LifetimeSafetyOpts &Opts,
LifetimeSafetyStats &Stats, bool CollectStats);
namespace internal {
diff --git a/clang/lib/Analysis/LifetimeSafety/Checker.cpp b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
index c258a1dc3596c..746ebbfb15c39 100644
--- a/clang/lib/Analysis/LifetimeSafety/Checker.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/Checker.cpp
@@ -68,6 +68,7 @@ class LifetimeChecker {
LifetimeSafetySemaHelper *SemaHelper;
ASTContext *
const Decl *FD;
+ const LifetimeSafetyOpts &LSOpts;
static SourceLocation
GetFactLoc(llvm::PointerUnion<const UseFact *, const OriginEscapesFact *> F) {
@@ -87,10 +88,11 @@ class LifetimeChecker {
const MovedLoansAnalysis &MovedLoans,
const LiveOriginsAnalysis &LiveOrigins, FactManager &FM,
AnalysisDeclContext &ADC,
- LifetimeSafetySemaHelper *SemaHelper)
+ LifetimeSafetySemaHelper *SemaHelper,
+ const LifetimeSafetyOpts &LSOpts)
: LoanPropagation(LoanPropagation), MovedLoans(MovedLoans),
LiveOrigins(LiveOrigins), FactMgr(FM), SemaHelper(SemaHelper),
- AST(ADC.getASTContext()), FD(ADC.getDecl()) {
+ AST(ADC.getASTContext()), FD(ADC.getDecl()), LSOpts(LSOpts) {
for (const CFGBlock *B : *ADC.getAnalysis<PostOrderCFGView>())
for (const Fact *F : FactMgr.getFacts(B))
if (const auto *EF = F->getAs<ExpireFact>())
@@ -398,6 +400,9 @@ class LifetimeChecker {
void suggestAnnotations() {
if (!SemaHelper)
return;
+ if (!LSOpts.SuggestAnnotations)
+ return;
+ llvm::TimeTraceScope TimeTrace("SuggestAnnotations");
for (auto [Target, EscapeTarget] : AnnotationWarningsMap) {
if (const auto *PVD = Target.dyn_cast<const ParmVarDecl *>())
suggestWithScopeForParmVar(PVD, EscapeTarget);
@@ -535,9 +540,10 @@ void runLifetimeChecker(const LoanPropagationAnalysis &LP,
const MovedLoansAnalysis &MovedLoans,
const LiveOriginsAnalysis &LO, FactManager &FactMgr,
AnalysisDeclContext &ADC,
- LifetimeSafetySemaHelper *SemaHelper) {
+ LifetimeSafetySemaHelper *SemaHelper,
+ const LifetimeSafetyOpts &LSOpts) {
llvm::TimeTraceScope TimeProfile("LifetimeChecker");
- LifetimeChecker Checker(LP, MovedLoans, LO, FactMgr, ADC, SemaHelper);
+ LifetimeChecker Checker(LP, MovedLoans, LO, FactMgr, ADC, SemaHelper, LSOpts);
}
} // namespace clang::lifetimes::internal
diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
index 714f979fa5ee7..680095a54177c 100644
--- a/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
+++ b/clang/lib/Analysis/LifetimeSafety/LifetimeSafety.cpp
@@ -96,7 +96,7 @@ void LifetimeSafetyAnalysis::run() {
Factory.MovedLoansMapFactory);
runLifetimeChecker(*LoanPropagation, *MovedLoans, *LiveOrigins, *FactMgr, AC,
- SemaHelper);
+ SemaHelper, LSOpts);
DEBUG_WITH_TYPE("PrintCFG", Cfg.dump(AC.getASTContext().getLangOpts(),
/*ShowColors=*/true));
@@ -122,11 +122,8 @@ void collectLifetimeStats(AnalysisDeclContext &AC, OriginManager &OM,
void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC,
LifetimeSafetySemaHelper *SemaHelper,
+ const LifetimeSafetyOpts &LSOpts,
LifetimeSafetyStats &Stats, bool CollectStats) {
- LifetimeSafetyOpts LSOpts;
- LSOpts.MaxCFGBlocks =
- AC.getASTContext().getLangOpts().LifetimeSafetyMaxCFGBlocks;
-
internal::LifetimeSafetyAnalysis Analysis(AC, SemaHelper, LSOpts);
Analysis.run();
if (CollectStats)
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 52fe7765c6c6a..e070d9f1a9b85 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2929,7 +2929,9 @@ LifetimeSafetyTUAnalysis(Sema &S, TranslationUnitDecl *TU,
AC.getCFGBuildOptions().AddCXXDefaultInitExprInCtors = true;
AC.getCFGBuildOptions().setAllAlwaysAdd();
if (AC.getCFG())
- runLifetimeSafetyAnalysis(AC, &SemaHelper, LSStats, S.CollectStats);
+ runLifetimeSafetyAnalysis(AC, &SemaHelper,
+ lifetimes::GetLifetimeSafetyOpts(S, FD),
+ LSStats, S.CollectStats);
}
}
@@ -3159,13 +3161,12 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
}
}
- // TODO: Enable lifetime safety analysis for other languages once it is
- // stable.
if (EnableLifetimeSafetyAnalysis) {
if (AC.getCFG()) {
lifetimes::LifetimeSafetySemaHelperImpl LifetimeSafetySemaHelper(S);
- lifetimes::runLifetimeSafetyAnalysis(AC, &LifetimeSafetySemaHelper,
- LSStats, S.CollectStats);
+ lifetimes::runLifetimeSafetyAnalysis(
+ AC, &LifetimeSafetySemaHelper, lifetimes::GetLifetimeSafetyOpts(S, D),
+ LSStats, S.CollectStats);
}
}
// Check for violations of "called once" parameter properties.
diff --git a/clang/lib/Sema/SemaLifetimeSafety.h b/clang/lib/Sema/SemaLifetimeSafety.h
index 7c78a6a1e8c31..a3d546792fe41 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -76,6 +76,26 @@ inline bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D) {
return false;
}
+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_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 LifetimeSafetyOpts GetLifetimeSafetyOpts(Sema &S, const Decl *D) {
+ LifetimeSafetyOpts LSOpts;
+ LSOpts.MaxCFGBlocks = S.getLangOpts().LifetimeSafetyMaxCFGBlocks;
+ LSOpts.SuggestAnnotations = ShouldSuggestLifetimeAnnotations(S, D);
+ return LSOpts;
+}
+
class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
public:
diff --git a/clang/test/Sema/LifetimeSafety/safety.cpp b/clang/test/Sema/LifetimeSafety/safety.cpp
index b59fac191dcfb..2c2d62b25b6c8 100644
--- a/clang/test/Sema/LifetimeSafety/safety.cpp
+++ b/clang/test/Sema/LifetimeSafety/safety.cpp
@@ -3955,3 +3955,9 @@ struct [[gsl::Pointer()]] PtrWithInt { int x; };
PtrWithInt f() {
return PtrWithInt{10};
}
+
+// This would normally trigger a suggestion warning if -Wlifetime-safety-suggestions was on.
+// Since it is off, we expect NO warnings or notes here.
+View suggestion_disabled_test(View a) {
+ return a;
+}
More information about the cfe-commits
mailing list