clang 23.0.0git
SemaLifetimeSafety.h
Go to the documentation of this file.
1//===--- SemaLifetimeSafety.h - Sema support for lifetime safety =---------==//
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 Sema-specific implementation for lifetime safety
10// analysis. It provides diagnostic reporting and helper functions that bridge
11// the lifetime safety analysis framework with Sema's diagnostic engine.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_LIB_SEMA_SEMALIFETIMESAFETY_H
16#define LLVM_CLANG_LIB_SEMA_SEMALIFETIMESAFETY_H
17
21#include "clang/Lex/Lexer.h"
22#include "clang/Sema/Sema.h"
23#include <string>
24
25namespace clang::lifetimes {
26
27inline bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D) {
28 if (S.getLangOpts().DebugRunLifetimeSafety)
29 return true;
31 constexpr unsigned DiagIDs[] = {
32 diag::warn_lifetime_safety_use_after_scope,
33 diag::warn_lifetime_safety_use_after_scope_moved,
34 diag::warn_lifetime_safety_use_after_free,
35 diag::warn_lifetime_safety_return_stack_addr,
36 diag::warn_lifetime_safety_return_stack_addr_moved,
37 diag::warn_lifetime_safety_invalidation,
38 diag::warn_lifetime_safety_dangling_field,
39 diag::warn_lifetime_safety_dangling_field_moved,
40 diag::warn_lifetime_safety_dangling_global,
41 diag::warn_lifetime_safety_dangling_global_moved,
42 diag::warn_lifetime_safety_noescape_escapes,
43 diag::warn_lifetime_safety_lifetimebound_violation,
44 diag::warn_lifetime_safety_cross_tu_misplaced_lifetimebound,
45 diag::warn_lifetime_safety_intra_tu_misplaced_lifetimebound,
46 diag::warn_lifetime_safety_invalidated_field,
47 diag::warn_lifetime_safety_invalidated_global,
48 diag::warn_lifetime_safety_cross_tu_param_suggestion,
49 diag::warn_lifetime_safety_intra_tu_param_suggestion,
50 diag::warn_lifetime_safety_cross_tu_this_suggestion,
51 diag::warn_lifetime_safety_intra_tu_this_suggestion};
52 for (unsigned DiagID : DiagIDs)
53 if (!Diags.isIgnored(DiagID, D->getBeginLoc()))
54 return true;
55 return false;
56}
57
59
60public:
62
63 void reportUseAfterScope(const Expr *IssueExpr, const Expr *UseExpr,
64 const Expr *MovedExpr,
65 SourceLocation FreeLoc) override {
66 unsigned DiagID = MovedExpr
67 ? diag::warn_lifetime_safety_use_after_scope_moved
68 : diag::warn_lifetime_safety_use_after_scope;
69
70 S.Diag(IssueExpr->getExprLoc(), DiagID)
71 << getDiagSubjectDescription(IssueExpr) << IssueExpr->getSourceRange();
72 if (MovedExpr)
73 S.Diag(MovedExpr->getExprLoc(), diag::note_lifetime_safety_moved_here)
74 << MovedExpr->getSourceRange();
75 S.Diag(FreeLoc, diag::note_lifetime_safety_destroyed_here);
76 S.Diag(UseExpr->getExprLoc(), diag::note_lifetime_safety_used_here)
77 << UseExpr->getSourceRange();
78 }
79
80 void reportUseAfterReturn(const Expr *IssueExpr, const Expr *ReturnExpr,
81 const Expr *MovedExpr) override {
82 unsigned DiagID = MovedExpr
83 ? diag::warn_lifetime_safety_return_stack_addr_moved
84 : diag::warn_lifetime_safety_return_stack_addr;
85
86 S.Diag(IssueExpr->getExprLoc(), DiagID)
87 << getDiagSubjectDescription(IssueExpr) << IssueExpr->getSourceRange();
88
89 if (MovedExpr)
90 S.Diag(MovedExpr->getExprLoc(), diag::note_lifetime_safety_moved_here)
91 << MovedExpr->getSourceRange();
92 S.Diag(ReturnExpr->getExprLoc(), diag::note_lifetime_safety_returned_here)
93 << ReturnExpr->getSourceRange();
94 }
95
96 void reportDanglingField(const Expr *IssueExpr,
97 const FieldDecl *DanglingField,
98 const Expr *MovedExpr,
99 SourceLocation ExpiryLoc) override {
100 unsigned DiagID = MovedExpr
101 ? diag::warn_lifetime_safety_dangling_field_moved
102 : diag::warn_lifetime_safety_dangling_field;
103
104 S.Diag(IssueExpr->getExprLoc(), DiagID)
105 << getDiagSubjectDescription(IssueExpr)
106 << getDiagSubjectDescription(DanglingField)
107 << IssueExpr->getSourceRange();
108 if (MovedExpr)
109 S.Diag(MovedExpr->getExprLoc(), diag::note_lifetime_safety_moved_here)
110 << MovedExpr->getSourceRange();
111 S.Diag(DanglingField->getLocation(),
112 diag::note_lifetime_safety_dangling_field_here)
113 << DanglingField->getEndLoc();
114 }
115
116 void reportDanglingGlobal(const Expr *IssueExpr,
117 const VarDecl *DanglingGlobal,
118 const Expr *MovedExpr,
119 SourceLocation ExpiryLoc) override {
120 unsigned DiagID = MovedExpr
121 ? diag::warn_lifetime_safety_dangling_global_moved
122 : diag::warn_lifetime_safety_dangling_global;
123
124 S.Diag(IssueExpr->getExprLoc(), DiagID)
125 << getDiagSubjectDescription(IssueExpr)
126 << getDiagSubjectDescription(DanglingGlobal)
127 << IssueExpr->getSourceRange();
128 if (MovedExpr)
129 S.Diag(MovedExpr->getExprLoc(), diag::note_lifetime_safety_moved_here)
130 << MovedExpr->getSourceRange();
131 if (DanglingGlobal->isStaticLocal() || DanglingGlobal->isStaticDataMember())
132 S.Diag(DanglingGlobal->getLocation(),
133 diag::note_lifetime_safety_dangling_static_here)
134 << DanglingGlobal->getEndLoc();
135 else
136 S.Diag(DanglingGlobal->getLocation(),
137 diag::note_lifetime_safety_dangling_global_here)
138 << DanglingGlobal->getEndLoc();
139 }
140
141 void reportUseAfterInvalidation(const Expr *IssueExpr, const Expr *UseExpr,
142 const Expr *InvalidationExpr) override {
143 auto WarnDiag = isa<CXXDeleteExpr>(InvalidationExpr)
144 ? diag::warn_lifetime_safety_use_after_free
145 : diag::warn_lifetime_safety_invalidation;
146 auto UseDiag = isa<CXXDeleteExpr>(InvalidationExpr)
147 ? diag::note_lifetime_safety_freed_here
148 : diag::note_lifetime_safety_invalidated_here;
149 S.Diag(IssueExpr->getExprLoc(), WarnDiag)
150 << false << IssueExpr->getSourceRange();
151 S.Diag(InvalidationExpr->getExprLoc(), UseDiag)
152 << InvalidationExpr->getSourceRange();
153 S.Diag(UseExpr->getExprLoc(), diag::note_lifetime_safety_used_here)
154 << UseExpr->getSourceRange();
155 }
156 void reportUseAfterInvalidation(const ParmVarDecl *PVD, const Expr *UseExpr,
157 const Expr *InvalidationExpr) override {
158
159 auto WarnDiag = isa<CXXDeleteExpr>(InvalidationExpr)
160 ? diag::warn_lifetime_safety_use_after_free
161 : diag::warn_lifetime_safety_invalidation;
162 auto UseDiag = isa<CXXDeleteExpr>(InvalidationExpr)
163 ? diag::note_lifetime_safety_freed_here
164 : diag::note_lifetime_safety_invalidated_here;
165
166 S.Diag(PVD->getSourceRange().getBegin(), WarnDiag)
167 << true << PVD->getSourceRange();
168 S.Diag(InvalidationExpr->getExprLoc(), UseDiag)
169 << InvalidationExpr->getSourceRange();
170 S.Diag(UseExpr->getExprLoc(), diag::note_lifetime_safety_used_here)
171 << UseExpr->getSourceRange();
172 }
173
174 void reportInvalidatedField(const Expr *IssueExpr,
175 const FieldDecl *DanglingField,
176 const Expr *InvalidationExpr) override {
177 auto InvalidationDiag = isa<CXXDeleteExpr>(InvalidationExpr)
178 ? diag::note_lifetime_safety_freed_here
179 : diag::note_lifetime_safety_invalidated_here;
180 S.Diag(IssueExpr->getExprLoc(),
181 diag::warn_lifetime_safety_invalidated_field)
182 << false << IssueExpr->getSourceRange();
183 S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
184 << InvalidationExpr->getSourceRange();
185 S.Diag(DanglingField->getLocation(),
186 diag::note_lifetime_safety_dangling_field_here)
187 << DanglingField->getEndLoc();
188 }
189
191 const FieldDecl *DanglingField,
192 const Expr *InvalidationExpr) override {
193 auto InvalidationDiag = isa<CXXDeleteExpr>(InvalidationExpr)
194 ? diag::note_lifetime_safety_freed_here
195 : diag::note_lifetime_safety_invalidated_here;
196 S.Diag(PVD->getSourceRange().getBegin(),
197 diag::warn_lifetime_safety_invalidated_field)
198 << true << PVD->getSourceRange();
199 S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
200 << InvalidationExpr->getSourceRange();
201 S.Diag(DanglingField->getLocation(),
202 diag::note_lifetime_safety_dangling_field_here)
203 << DanglingField->getEndLoc();
204 }
205
206 void reportInvalidatedGlobal(const Expr *IssueExpr,
207 const VarDecl *DanglingGlobal,
208 const Expr *InvalidationExpr) override {
209 auto InvalidationDiag = isa<CXXDeleteExpr>(InvalidationExpr)
210 ? diag::note_lifetime_safety_freed_here
211 : diag::note_lifetime_safety_invalidated_here;
212 S.Diag(IssueExpr->getExprLoc(),
213 diag::warn_lifetime_safety_invalidated_global)
214 << false << IssueExpr->getSourceRange();
215 S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
216 << InvalidationExpr->getSourceRange();
217 if (DanglingGlobal->isStaticLocal() || DanglingGlobal->isStaticDataMember())
218 S.Diag(DanglingGlobal->getLocation(),
219 diag::note_lifetime_safety_dangling_static_here)
220 << DanglingGlobal->getEndLoc();
221 else
222 S.Diag(DanglingGlobal->getLocation(),
223 diag::note_lifetime_safety_dangling_global_here)
224 << DanglingGlobal->getEndLoc();
225 }
226
228 const VarDecl *DanglingGlobal,
229 const Expr *InvalidationExpr) override {
230 auto InvalidationDiag = isa<CXXDeleteExpr>(InvalidationExpr)
231 ? diag::note_lifetime_safety_freed_here
232 : diag::note_lifetime_safety_invalidated_here;
233 S.Diag(PVD->getSourceRange().getBegin(),
234 diag::warn_lifetime_safety_invalidated_global)
235 << true << PVD->getSourceRange();
236 S.Diag(InvalidationExpr->getExprLoc(), InvalidationDiag)
237 << InvalidationExpr->getSourceRange();
238 if (DanglingGlobal->isStaticLocal() || DanglingGlobal->isStaticDataMember())
239 S.Diag(DanglingGlobal->getLocation(),
240 diag::note_lifetime_safety_dangling_static_here)
241 << DanglingGlobal->getEndLoc();
242 else
243 S.Diag(DanglingGlobal->getLocation(),
244 diag::note_lifetime_safety_dangling_global_here)
245 << DanglingGlobal->getEndLoc();
246 }
247
249 const ParmVarDecl *ParmToAnnotate,
250 EscapingTarget Target) override {
251 unsigned DiagID =
253 ? diag::warn_lifetime_safety_cross_tu_param_suggestion
254 : diag::warn_lifetime_safety_intra_tu_param_suggestion;
255
256 auto [InsertionPoint, FixItText] = getLifetimeBoundFixIt(ParmToAnnotate);
257
258 S.Diag(ParmToAnnotate->getBeginLoc(), DiagID)
259 << ParmToAnnotate->getSourceRange()
260 << FixItHint::CreateInsertion(InsertionPoint, FixItText);
261
262 if (const auto *EscapeExpr = Target.dyn_cast<const Expr *>())
263 S.Diag(EscapeExpr->getBeginLoc(),
264 diag::note_lifetime_safety_suggestion_returned_here)
265 << EscapeExpr->getSourceRange();
266 else if (const auto *EscapeField = Target.dyn_cast<const FieldDecl *>())
267 S.Diag(EscapeField->getLocation(),
268 diag::note_lifetime_safety_escapes_to_field_here)
269 << EscapeField->getSourceRange();
270 }
271
273 const ParmVarDecl *ParmWithLifetimebound) override {
274 const auto *Attr = ParmWithLifetimebound->getAttr<LifetimeBoundAttr>();
275 StringRef ParamName = ParmWithLifetimebound->getName();
276 bool HasName = ParamName.size() > 0;
277 S.Diag(Attr->getLocation(),
278 diag::warn_lifetime_safety_lifetimebound_violation)
279 << HasName << ParamName << Attr->getRange();
280 }
281
283 const CXXMethodDecl *MDWithLifetimebound) override {
284 const auto *Attr =
285 getImplicitObjectParamLifetimeBoundAttr(MDWithLifetimebound);
286 assert(Attr && "Expected lifetimebound attribute");
287 S.Diag(Attr->getLocation(),
288 diag::warn_lifetime_safety_lifetimebound_violation)
289 << 2 << "" << Attr->getRange();
290 }
291
293 const CXXMethodDecl *FDef,
294 const CXXMethodDecl *FDecl) override {
296 assert(Attr && "Expected lifetimebound attribute");
297 unsigned DiagID =
299 ? diag::warn_lifetime_safety_cross_tu_misplaced_lifetimebound
300 : diag::warn_lifetime_safety_intra_tu_misplaced_lifetimebound;
301
302 auto [InsertionPoint, FixItText] = getLifetimeBoundFixIt(FDecl);
303
304 // Do not emit fix-its in macros or at invalid locations.
305 bool IsMacro =
306 FDecl->getBeginLoc().isMacroID() || InsertionPoint.isMacroID();
307
308 if (IsMacro || InsertionPoint.isInvalid())
309 S.Diag(FDecl->getLocation(), DiagID);
310 else
311 S.Diag(InsertionPoint, DiagID)
312 << FixItHint::CreateInsertion(InsertionPoint, FixItText);
313
314 S.Diag(Attr->getLocation(), diag::note_lifetime_safety_lifetimebound_here)
315 << Attr->getRange();
316 }
317
319 const ParmVarDecl *PVDDef,
320 const ParmVarDecl *PVDDecl) override {
321
322 const auto *Attr = PVDDef->getAttr<LifetimeBoundAttr>();
323 assert(Attr && "Expected lifetimebound attribute");
324 unsigned DiagID =
326 ? diag::warn_lifetime_safety_cross_tu_misplaced_lifetimebound
327 : diag::warn_lifetime_safety_intra_tu_misplaced_lifetimebound;
328
329 auto [InsertionPoint, FixItText] = getLifetimeBoundFixIt(PVDDecl);
330
331 // Do not emit fix-its in macros or at invalid locations.
332 bool IsMacro =
333 PVDDecl->getBeginLoc().isMacroID() || InsertionPoint.isMacroID();
334
335 if (IsMacro || InsertionPoint.isInvalid())
336 S.Diag(PVDDecl->getBeginLoc(), DiagID) << PVDDecl->getSourceRange();
337 else
338 S.Diag(PVDDecl->getBeginLoc(), DiagID)
339 << PVDDecl->getSourceRange()
340 << FixItHint::CreateInsertion(InsertionPoint, FixItText);
341
342 S.Diag(Attr->getLocation(), diag::note_lifetime_safety_lifetimebound_here)
343 << Attr->getRange();
344 }
345
347 const CXXMethodDecl *MD,
348 const Expr *EscapeExpr) override {
349 unsigned DiagID = (Scope == WarningScope::CrossTU)
350 ? diag::warn_lifetime_safety_cross_tu_this_suggestion
351 : diag::warn_lifetime_safety_intra_tu_this_suggestion;
352
353 auto [InsertionPoint, FixItText] = getLifetimeBoundFixIt(MD);
354
355 S.Diag(InsertionPoint, DiagID)
356 << MD->getNameInfo().getSourceRange()
357 << FixItHint::CreateInsertion(InsertionPoint, FixItText);
358
359 S.Diag(EscapeExpr->getBeginLoc(),
360 diag::note_lifetime_safety_suggestion_returned_here)
361 << EscapeExpr->getSourceRange();
362 }
363
364 void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape,
365 const Expr *EscapeExpr) override {
366 S.Diag(ParmWithNoescape->getBeginLoc(),
367 diag::warn_lifetime_safety_noescape_escapes)
368 << ParmWithNoescape->getSourceRange();
369
370 S.Diag(EscapeExpr->getBeginLoc(),
371 diag::note_lifetime_safety_suggestion_returned_here)
372 << EscapeExpr->getSourceRange();
373 }
374
375 void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape,
376 const FieldDecl *EscapeField) override {
377 S.Diag(ParmWithNoescape->getBeginLoc(),
378 diag::warn_lifetime_safety_noescape_escapes)
379 << ParmWithNoescape->getSourceRange();
380
381 S.Diag(EscapeField->getLocation(),
382 diag::note_lifetime_safety_escapes_to_field_here)
383 << EscapeField->getEndLoc();
384 }
385
386 void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape,
387 const VarDecl *EscapeGlobal) override {
388 S.Diag(ParmWithNoescape->getBeginLoc(),
389 diag::warn_lifetime_safety_noescape_escapes)
390 << ParmWithNoescape->getSourceRange();
391 if (EscapeGlobal->isStaticLocal() || EscapeGlobal->isStaticDataMember())
392 S.Diag(EscapeGlobal->getLocation(),
393 diag::note_lifetime_safety_escapes_to_static_storage_here)
394 << EscapeGlobal->getEndLoc();
395 else
396 S.Diag(EscapeGlobal->getLocation(),
397 diag::note_lifetime_safety_escapes_to_global_here)
398 << EscapeGlobal->getEndLoc();
399 }
400
402 S.addLifetimeBoundToImplicitThis(const_cast<CXXMethodDecl *>(MD));
403 }
404
405private:
406 std::pair<SourceLocation, StringRef>
407 getLifetimeBoundFixIt(const ParmVarDecl *Decl) {
410 StringRef FixItText = " [[clang::lifetimebound]]";
411
412 if (!Decl->getIdentifier()) {
413 // For unnamed parameters, placing attributes after the type would be
414 // parsed as a type attribute, not a parameter attribute.
415 InsertionPoint = Decl->getBeginLoc();
416 FixItText = "[[clang::lifetimebound]] ";
417 } else if (Decl->hasDefaultArg()) {
418 // If the parameter has a default argument, place the attribute after the
419 // named argument.
420 InsertionPoint = Lexer::getLocForEndOfToken(
422 }
423 return {InsertionPoint, FixItText};
424 }
425
426 std::pair<SourceLocation, StringRef>
427 getLifetimeBoundFixIt(const CXXMethodDecl *MD) {
428 const auto MDL = MD->getTypeSourceInfo()->getTypeLoc();
429 SourceLocation InsertionPoint = Lexer::getLocForEndOfToken(
430 MDL.getEndLoc(), 0, S.getSourceManager(), S.getLangOpts());
431
432 if (const auto *FPT = MD->getType()->getAs<FunctionProtoType>();
433 FPT && FPT->hasTrailingReturn()) {
434 // For trailing return types, 'getEndLoc()' includes the return type
435 // after '->', placing the attribute in an invalid position.
436 // Instead use 'getLocalRangeEnd()' which gives the '->' location
437 // for trailing returns, so find the last token before it.
438 const auto FTL = MDL.getAs<FunctionTypeLoc>();
439 assert(FTL);
440 InsertionPoint = Lexer::getLocForEndOfToken(
441 Lexer::findPreviousToken(FTL.getLocalRangeEnd(), S.getSourceManager(),
442 S.getLangOpts(),
443 /*IncludeComments=*/false)
444 ->getLocation(),
445 0, S.getSourceManager(), S.getLangOpts());
446 }
447 return {InsertionPoint, " [[clang::lifetimebound]]"};
448 }
449
450 std::string getDiagSubjectDescription(const ValueDecl *VD) {
451 std::string Res;
452 llvm::raw_string_ostream OS(Res);
453 if (isa<FieldDecl>(VD)) {
454 OS << "field";
455 } else if (isa<ParmVarDecl>(VD)) {
456 OS << "parameter";
457 } else if (const auto *Var = dyn_cast<VarDecl>(VD)) {
458 if (Var->isStaticLocal() || Var->isStaticDataMember())
459 OS << "static variable";
460 else if (Var->hasGlobalStorage())
461 OS << "global variable";
462 else
463 OS << "local variable";
464 } else {
465 OS << "variable";
466 }
467 OS << " '";
468 VD->getNameForDiagnostic(OS, S.getPrintingPolicy(), /*Qualified=*/false);
469 OS << "'";
470 return Res;
471 }
472
473 std::string getDiagSubjectDescription(const Expr *E) {
475 return "local temporary object";
476
477 if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
478 return getDiagSubjectDescription(DRE->getDecl());
479 // TODO: Handle other expression types.
480 return "";
481 }
482
483 Sema &S;
484};
485
486} // namespace clang::lifetimes
487
488#endif // LLVM_CLANG_LIB_SEMA_SEMALIFETIMESAFETY_H
Attr - This represents one attribute.
Definition Attr.h:46
SourceLocation getLocation() const
Definition Attr.h:99
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2132
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
SourceLocation getEndLoc() const LLVM_READONLY
Definition DeclBase.h:443
T * getAttr() const
Definition DeclBase.h:581
SourceLocation getLocation() const
Definition DeclBase.h:447
SourceLocation getBeginLoc() const LLVM_READONLY
Definition DeclBase.h:439
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:831
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:233
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition Diagnostic.h:960
This represents one expression.
Definition Expr.h:112
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition Expr.cpp:282
Represents a member of a struct/union/class.
Definition Decl.h:3166
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Definition Diagnostic.h:104
DeclarationNameInfo getNameInfo() const
Definition Decl.h:2201
static std::optional< Token > findPreviousToken(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts, bool IncludeComments)
Finds the token that comes before the given location.
Definition Lexer.cpp:1406
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Definition Lexer.cpp:881
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
Represents a parameter to a function.
Definition Decl.h:1808
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:2955
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
DiagnosticsEngine & getDiagnostics() const
Definition Sema.h:936
const LangOptions & getLangOpts() const
Definition Sema.h:932
SourceManager & getSourceManager() const
Definition Sema.h:937
Encodes a location in the source.
SourceLocation getBegin() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
Represents a variable declaration or definition.
Definition Decl.h:924
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition Decl.h:1296
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1206
void reportUseAfterReturn(const Expr *IssueExpr, const Expr *ReturnExpr, const Expr *MovedExpr) override
void reportMisplacedLifetimebound(WarningScope Scope, const ParmVarDecl *PVDDef, const ParmVarDecl *PVDDecl) override
void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape, const Expr *EscapeExpr) override
void reportUseAfterInvalidation(const ParmVarDecl *PVD, const Expr *UseExpr, const Expr *InvalidationExpr) override
void reportInvalidatedField(const ParmVarDecl *PVD, const FieldDecl *DanglingField, const Expr *InvalidationExpr) override
void reportLifetimeboundViolation(const CXXMethodDecl *MDWithLifetimebound) override
void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape, const VarDecl *EscapeGlobal) override
void suggestLifetimeboundToImplicitThis(WarningScope Scope, const CXXMethodDecl *MD, const Expr *EscapeExpr) override
void reportInvalidatedGlobal(const ParmVarDecl *PVD, const VarDecl *DanglingGlobal, const Expr *InvalidationExpr) override
void suggestLifetimeboundToParmVar(WarningScope Scope, const ParmVarDecl *ParmToAnnotate, EscapingTarget Target) override
void reportDanglingGlobal(const Expr *IssueExpr, const VarDecl *DanglingGlobal, const Expr *MovedExpr, SourceLocation ExpiryLoc) override
void reportInvalidatedField(const Expr *IssueExpr, const FieldDecl *DanglingField, const Expr *InvalidationExpr) override
void reportDanglingField(const Expr *IssueExpr, const FieldDecl *DanglingField, const Expr *MovedExpr, SourceLocation ExpiryLoc) override
void addLifetimeBoundToImplicitThis(const CXXMethodDecl *MD) override
void reportUseAfterInvalidation(const Expr *IssueExpr, const Expr *UseExpr, const Expr *InvalidationExpr) override
void reportMisplacedLifetimebound(WarningScope Scope, const CXXMethodDecl *FDef, const CXXMethodDecl *FDecl) override
void reportUseAfterScope(const Expr *IssueExpr, const Expr *UseExpr, const Expr *MovedExpr, SourceLocation FreeLoc) override
void reportNoescapeViolation(const ParmVarDecl *ParmWithNoescape, const FieldDecl *EscapeField) override
void reportInvalidatedGlobal(const Expr *IssueExpr, const VarDecl *DanglingGlobal, const Expr *InvalidationExpr) override
void reportLifetimeboundViolation(const ParmVarDecl *ParmWithLifetimebound) override
llvm::PointerUnion< const Expr *, const FieldDecl *, const VarDecl * > EscapingTarget
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
const LifetimeBoundAttr * getDirectImplicitObjectLifetimeBoundAttr(const FunctionDecl *FD)
WarningScope
Enum to track functions visible across or within TU.
const LifetimeBoundAttr * getImplicitObjectParamLifetimeBoundAttr(const FunctionDecl *FD)
bool IsLifetimeSafetyEnabled(Sema &S, const Decl *D)
bool isa(CodeGen::Address addr)
Definition Address.h:330
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.