clang 24.0.0git
LifetimeAnnotations.h
Go to the documentation of this file.
1//===- LifetimeAnnotations.h - -*--------------- 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// Helper functions to inspect and infer lifetime annotations.
9//===----------------------------------------------------------------------===//
10#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMEANNOTATIONS_H
11#define LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMEANNOTATIONS_H
12
13#include "clang/AST/Attr.h"
14#include "clang/AST/DeclCXX.h"
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/PointerUnion.h"
17#include "llvm/ADT/SmallVector.h"
18#include <optional>
19
20namespace clang {
21class LifetimeBoundAttr;
22} // namespace clang
23
24namespace clang ::lifetimes {
25
26// This function is needed because Decl::isInStdNamespace will return false for
27// iterators in some STL implementations due to them being defined in a
28// namespace outside of the std namespace.
29bool isInStlNamespace(const Decl *D);
30
31bool isPointerLikeType(QualType QT);
32
33/// Returns the most recent declaration of the method to ensure all
34/// lifetime-bound attributes from redeclarations are considered.
35const FunctionDecl *getDeclWithMergedLifetimeBoundAttrs(const FunctionDecl *FD);
36
37/// Returns the most recent declaration of the method to ensure all
38/// lifetime-bound attributes from redeclarations are considered.
39const CXXMethodDecl *
40getDeclWithMergedLifetimeBoundAttrs(const CXXMethodDecl *CMD);
41
42// Return true if this is an "normal" assignment operator.
43// We assume that a normal assignment operator always returns *this, that is,
44// an lvalue reference that is the same type as the implicit object parameter
45// (or the LHS for a non-member operator==).
46bool isNormalAssignmentOperator(const FunctionDecl *FD);
47
48/// Returns true if this is an assignment operator where the parameter
49/// has the lifetimebound attribute.
50bool isAssignmentOperatorLifetimeBound(const CXXMethodDecl *CMD);
51
52/// Returns the lifetimebound attribute for the implicit this parameter, if it
53/// exists on the current type.
54const LifetimeBoundAttr *
56
57/// Returns the lifetimebound attribute for the implicit this parameter, if it
58/// exists on any redeclaration.
59const LifetimeBoundAttr *
61
62/// Returns true if the implicit object parameter (this) should be considered
63/// lifetimebound, either due to an explicit lifetimebound attribute on the
64/// method or because it's a normal assignment operator.
65bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD);
66
67/// Check if a function has a lifetime_capture_by attribute on its declaration
68/// or its function type (which represents the implicit 'this' parameter for
69/// methods). Returns the attribute if found, nullptr otherwise.
70const LifetimeCaptureByAttr *
71getCaptureByAttrFromFunctionType(const FunctionDecl *FD);
72
74 llvm::PointerUnion<const ParmVarDecl *, const CXXMethodDecl *>;
75
76/// Stores the callee and normalized arguments for a function call.
78 const FunctionDecl *FD = nullptr;
80
81 explicit FunctionCallInfo(const Expr *Call);
82};
83
84/// Returns the parameter corresponding to argument I when the argument should
85/// be tracked for lifetime safety.
86std::optional<LifetimeBoundParamInfo>
88 unsigned I);
89
90/// Returns lifetime safety tracking info for the call argument containing
91/// Source.
92std::optional<LifetimeBoundParamInfo>
93getTrackingInfoForCallArg(const Expr *Call, const Expr *Source);
94
95// Returns true if the implicit object argument (this) of a method call should
96// be tracked for GSL lifetime analysis. This applies to STL methods that return
97// pointers or references that depend on the lifetime of the object, such as
98// container iterators (begin, end), data accessors (c_str, data, get),
99// element accessors (operator[], operator*, front, back, at), or propagating
100// operations (operator+, operator-, operator++, operator--).
101bool shouldTrackImplicitObjectArg(const Expr &ImplicitObjectArgument,
102 const CXXMethodDecl *Callee,
103 bool RunningUnderLifetimeSafety);
104
105// Returns true if the first argument of a free function should be tracked for
106// GSL lifetime analysis. This applies to STL free functions that take a pointer
107// to a GSL Owner or Pointer and return a pointer or reference that depends on
108// the lifetime of the argument, such as std::begin, std::data, std::get, or
109// std::any_cast.
110bool shouldTrackFirstArgument(const FunctionDecl *FD);
111
112// Returns true if the second argument of a free function should be tracked for
113// lifetime analysis. This applies to free operator functions that take a
114// GSL Pointer as their second argument.
115bool shouldTrackSecondArgument(const FunctionDecl *FD);
116
117// Tells whether the type is annotated with [[gsl::Pointer]].
118bool isGslPointerType(QualType QT);
119// Tells whether the type is annotated with [[gsl::Owner]].
120bool isGslOwnerType(QualType QT);
121bool isGslOwnerType(const CXXRecordDecl *RD);
122
123// Tells whether the given constructor belongs to an Owner type and the
124// parameter is of pointer type. This is useful to disable inference on owning
125// pointers being captured by owners.
126bool isOwnerPtrCtor(const CXXConstructorDecl *Ctor, const ParmVarDecl *PVD);
127
128// Returns true if the given method is std::unique_ptr::release().
129// This is treated as a move in lifetime analysis to avoid false-positives
130// when ownership is manually transferred.
131bool isUniquePtrRelease(const CXXMethodDecl &MD);
132
133// Returns true if the given method invalidates references tracked by lifetime
134// analysis (e.g. vector::push_back). Methods that only invalidate iterators but
135// not references (e.g. unordered_map::emplace) are not considered invalidating
136// here.
137//
138// Container invalidation rules are based on:
139// https://en.cppreference.com/w/cpp/container#Iterator_invalidation
140bool isInvalidationMethod(const CXXMethodDecl &MD);
141
142// Returns true if the function destroys its first argument
143// (e.g., destructors via implicit 'this', std::destroy_at).
144bool destructsFirstArg(const FunctionDecl &FD);
145
146/// Returns true if the function allocates memory that must be freed by the
147/// caller (e.g. functions annotated with `ownership_returns`, such as
148/// `__attribute__((ownership_returns(malloc)))`).
149bool isAllocatingFunction(const FunctionDecl &FD);
150
151/// Returns true if the function frees memory it takes ownership of (e.g.
152/// functions annotated with `ownership_takes`, such as
153/// `__attribute__((ownership_takes(malloc, 1)))`).
154bool isFreeingFunction(const FunctionDecl &FD);
155
156/// Returns true for standard library callable wrappers (e.g., std::function)
157/// that can propagate the stored lambda's origins.
158bool isStdCallableWrapperType(const CXXRecordDecl *RD);
159
160/// Returns true for std reference-cast builtins (e.g., std::move). Their result
161/// refers to the same object as the argument, so all origins propagate from
162/// argument to result.
163bool isStdReferenceCast(const FunctionDecl *FD);
164
165} // namespace clang::lifetimes
166
167#endif // LLVM_CLANG_ANALYSIS_ANALYSES_LIFETIMEANNOTATIONS_H
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
bool isAllocatingFunction(const FunctionDecl &FD)
Returns true if the function allocates memory that must be freed by the caller (e....
bool isInvalidationMethod(const CXXMethodDecl &MD)
bool isFreeingFunction(const FunctionDecl &FD)
Returns true if the function frees memory it takes ownership of (e.g.
bool isStdReferenceCast(const FunctionDecl *FD)
Returns true for std reference-cast builtins (e.g., std::move).
bool isAssignmentOperatorLifetimeBound(const CXXMethodDecl *CMD)
Returns true if this is an assignment operator where the parameter has the lifetimebound attribute.
bool isPointerLikeType(QualType QT)
bool shouldTrackImplicitObjectArg(const Expr &ImplicitObjectArgument, const CXXMethodDecl *Callee, bool RunningUnderLifetimeSafety)
bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD)
Returns true if the implicit object parameter (this) should be considered lifetimebound,...
std::optional< LifetimeBoundParamInfo > getTrackedArgInfo(const FunctionDecl *FD, llvm::ArrayRef< const Expr * > Args, unsigned I)
Returns the parameter corresponding to argument I when the argument should be tracked for lifetime sa...
bool shouldTrackFirstArgument(const FunctionDecl *FD)
bool shouldTrackSecondArgument(const FunctionDecl *FD)
bool destructsFirstArg(const FunctionDecl &FD)
const FunctionDecl * getDeclWithMergedLifetimeBoundAttrs(const FunctionDecl *FD)
Returns the most recent declaration of the method to ensure all lifetime-bound attributes from redecl...
const LifetimeBoundAttr * getImplicitObjectParamLifetimeBoundAttr(const FunctionDecl *FD)
Returns the lifetimebound attribute for the implicit this parameter, if it exists on any redeclaratio...
std::optional< LifetimeBoundParamInfo > getTrackingInfoForCallArg(const Expr *Call, const Expr *Source)
Returns lifetime safety tracking info for the call argument containing Source.
const LifetimeCaptureByAttr * getCaptureByAttrFromFunctionType(const FunctionDecl *FD)
Check if a function has a lifetime_capture_by attribute on its declaration or its function type (whic...
bool isOwnerPtrCtor(const CXXConstructorDecl *Ctor, const ParmVarDecl *PVD)
bool isNormalAssignmentOperator(const FunctionDecl *FD)
bool isUniquePtrRelease(const CXXMethodDecl &MD)
bool isInStlNamespace(const Decl *D)
llvm::PointerUnion< const ParmVarDecl *, const CXXMethodDecl * > LifetimeBoundParamInfo
bool isStdCallableWrapperType(const CXXRecordDecl *RD)
Returns true for standard library callable wrappers (e.g., std::function) that can propagate the stor...
const LifetimeBoundAttr * getDirectImplicitObjectLifetimeBoundAttr(const FunctionDecl *FD)
Returns the lifetimebound attribute for the implicit this parameter, if it exists on the current type...
bool isGslPointerType(QualType QT)
bool isGslOwnerType(QualType QT)
Top level wrappers for InstallAPI frontend operations.
llvm::SmallVector< const Expr *, 4 > Args