clang 23.0.0git
LifetimeSafety.h
Go to the documentation of this file.
1//===- LifetimeSafety.h - C++ Lifetime Safety Analysis -*----------- C++-*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the main entry point and orchestrator for the C++ Lifetime
10// Safety Analysis. It coordinates the entire analysis pipeline: fact
11// generation, loan propagation, live origins analysis, and enforcement of
12// lifetime safety policy.
13//
14// The analysis is based on the concepts of "origins" and "loans" to track
15// pointer lifetimes and detect issues like use-after-free and dangling
16// pointers. See the RFC for more details:
17// https://discourse.llvm.org/t/rfc-intra-procedural-lifetime-analysis-in-clang/86291
18//
19//===----------------------------------------------------------------------===//
20#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H
21#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H
22
23#include "clang/AST/Decl.h"
31#include "llvm/ADT/PointerUnion.h"
32#include <cstddef>
33#include <memory>
34
35namespace clang::lifetimes {
36
38 /// Maximum number of CFG blocks to analyze. Functions with larger CFGs will
39 /// be skipped.
41};
42
43/// Enum to track functions visible across or within TU.
44enum class SuggestionScope {
45 CrossTU, // For suggestions on declarations visible across Translation Units.
46 IntraTU // For suggestions on definitions local to a Translation Unit.
47};
48
49/// Abstract interface for operations requiring Sema access.
50///
51/// This class exists to break a circular dependency: the LifetimeSafety
52/// analysis target cannot directly depend on clangSema (which would create the
53/// cycle: clangSema -> clangAnalysis -> clangAnalysisLifetimeSafety ->
54/// clangSema).
55///
56/// Instead, this interface is implemented in AnalysisBasedWarnings.cpp (part of
57/// clangSema), allowing the analysis to report diagnostics and modify the AST
58/// through Sema without introducing a circular dependency.
60public:
62 virtual ~LifetimeSafetySemaHelper() = default;
63
64 virtual void reportUseAfterScope(const Expr *IssueExpr, const Expr *UseExpr,
65 const Expr *MovedExpr,
66 SourceLocation FreeLoc) {}
67
68 virtual void reportUseAfterReturn(const Expr *IssueExpr,
69 const Expr *ReturnExpr,
70 const Expr *MovedExpr,
71 SourceLocation ExpiryLoc) {}
72
73 virtual void reportDanglingField(const Expr *IssueExpr,
74 const FieldDecl *Field,
75 const Expr *MovedExpr,
76 SourceLocation ExpiryLoc) {}
77
78 virtual void reportDanglingGlobal(const Expr *IssueExpr,
79 const VarDecl *DanglingGlobal,
80 const Expr *MovedExpr,
81 SourceLocation ExpiryLoc) {}
82
83 // Reports when a reference/iterator is used after the container operation
84 // that invalidated it.
85 virtual void reportUseAfterInvalidation(const Expr *IssueExpr,
86 const Expr *UseExpr,
87 const Expr *InvalidationExpr) {}
88 virtual void reportUseAfterInvalidation(const ParmVarDecl *PVD,
89 const Expr *UseExpr,
90 const Expr *InvalidationExpr) {}
91
93 llvm::PointerUnion<const Expr *, const FieldDecl *, const VarDecl *>;
94
95 // Suggests lifetime bound annotations for function parameters.
99
100 // Reports misuse of [[clang::noescape]] when parameter escapes through return
101 virtual void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape,
102 const Expr *EscapeExpr) {}
103 // Reports misuse of [[clang::noescape]] when parameter escapes through field
104 virtual void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape,
105 const FieldDecl *EscapeField) {}
106 // Reports misuse of [[clang::noescape]] when parameter escapes through
107 // assignment to a global variable
108 virtual void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape,
109 const VarDecl *EscapeGlobal) {}
110
111 // Suggests lifetime bound annotations for implicit this.
113 const CXXMethodDecl *MD,
114 const Expr *EscapeExpr) {}
115
116 // Adds inferred lifetime bound attribute for implicit this to its
117 // TypeSourceInfo.
119};
120
121/// The main entry point for the analysis.
123 LifetimeSafetySemaHelper *SemaHelper,
124 LifetimeSafetyStats &Stats, bool CollectStats);
125
126namespace internal {
127
128void collectLifetimeStats(AnalysisDeclContext &AC, OriginManager &OM,
129 LifetimeSafetyStats &Stats);
130
131/// An object to hold the factories for immutable collections, ensuring
132/// that all created states share the same underlying memory management.
134 OriginLoanMap::Factory OriginMapFactory{/*canonicalize=*/false};
135 LoanSet::Factory LoanSetFactory{/*canonicalize=*/false};
136 MovedLoansMap::Factory MovedLoansMapFactory{/*canonicalize=*/false};
137 LivenessMap::Factory LivenessMapFactory{/*canonicalize=*/false};
138};
139
140/// Running the lifetime safety analysis and querying its results. It
141/// encapsulates the various dataflow analyses.
143public:
145 LifetimeSafetySemaHelper *SemaHelper,
146 const LifetimeSafetyOpts &LSOpts);
147
148 void run();
149
150 /// \note These are provided only for testing purposes.
152 return *LoanPropagation;
153 }
154 LiveOriginsAnalysis &getLiveOrigins() const { return *LiveOrigins; }
155 FactManager &getFactManager() { return *FactMgr; }
156
157private:
159 LifetimeSafetySemaHelper *SemaHelper;
160 const LifetimeSafetyOpts LSOpts;
161 LifetimeFactory Factory;
162 std::unique_ptr<FactManager> FactMgr;
163 std::unique_ptr<LiveOriginsAnalysis> LiveOrigins;
164 std::unique_ptr<LoanPropagationAnalysis> LoanPropagation;
165 std::unique_ptr<MovedLoansAnalysis> MovedLoans;
166};
167} // namespace internal
168} // namespace clang::lifetimes
169
170#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMESAFETY_H
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
AnalysisDeclContext contains the context data for the function, method or block under analysis.
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2136
This represents one expression.
Definition Expr.h:112
Represents a member of a struct/union/class.
Definition Decl.h:3175
Represents a parameter to a function.
Definition Decl.h:1805
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
Encodes a location in the source.
Represents a variable declaration or definition.
Definition Decl.h:926
Abstract interface for operations requiring Sema access.
virtual void reportUseAfterReturn(const Expr *IssueExpr, const Expr *ReturnExpr, const Expr *MovedExpr, SourceLocation ExpiryLoc)
virtual void reportUseAfterInvalidation(const ParmVarDecl *PVD, const Expr *UseExpr, const Expr *InvalidationExpr)
llvm::PointerUnion< const Expr *, const FieldDecl *, const VarDecl * > EscapingTarget
virtual void reportDanglingGlobal(const Expr *IssueExpr, const VarDecl *DanglingGlobal, const Expr *MovedExpr, SourceLocation ExpiryLoc)
virtual void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape, const VarDecl *EscapeGlobal)
virtual void suggestLifetimeboundToImplicitThis(SuggestionScope Scope, const CXXMethodDecl *MD, const Expr *EscapeExpr)
virtual void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape, const FieldDecl *EscapeField)
virtual void reportDanglingField(const Expr *IssueExpr, const FieldDecl *Field, const Expr *MovedExpr, SourceLocation ExpiryLoc)
virtual void addLifetimeBoundToImplicitThis(const CXXMethodDecl *MD)
virtual void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape, const Expr *EscapeExpr)
virtual void reportUseAfterScope(const Expr *IssueExpr, const Expr *UseExpr, const Expr *MovedExpr, SourceLocation FreeLoc)
virtual void suggestLifetimeboundToParmVar(SuggestionScope Scope, const ParmVarDecl *ParmToAnnotate, EscapingTarget Target)
virtual void reportUseAfterInvalidation(const Expr *IssueExpr, const Expr *UseExpr, const Expr *InvalidationExpr)
LifetimeSafetyAnalysis(AnalysisDeclContext &AC, LifetimeSafetySemaHelper *SemaHelper, const LifetimeSafetyOpts &LSOpts)
LoanPropagationAnalysis & getLoanPropagation() const
void collectLifetimeStats(AnalysisDeclContext &AC, OriginManager &OM, LifetimeSafetyStats &Stats)
SuggestionScope
Enum to track functions visible across or within TU.
void runLifetimeSafetyAnalysis(AnalysisDeclContext &AC, LifetimeSafetySemaHelper *SemaHelper, LifetimeSafetyStats &Stats, bool CollectStats)
The main entry point for the analysis.
size_t MaxCFGBlocks
Maximum number of CFG blocks to analyze.
An object to hold the factories for immutable collections, ensuring that all created states share the...