clang 24.0.0git
RawPtrRefSafetyModel.h
Go to the documentation of this file.
1//=======- RawPtrRefSafetyModel.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
9#ifndef LLVM_CLANG_ANALYZER_WEBKIT_RAWPTRREFSAFETYMODEL_H
10#define LLVM_CLANG_ANALYZER_WEBKIT_RAWPTRREFSAFETYMODEL_H
11
12#include "DiagOutputUtils.h"
13#include "PtrTypesSemantics.h"
14#include "clang/AST/Type.h"
15#include "llvm/Support/raw_ostream.h"
16#include <memory>
17#include <optional>
18#include <string>
19
20namespace clang {
21class CXXRecordDecl;
22class Decl;
23class Expr;
24class QualType;
25class SourceManager;
26
27/// Models one WebKit pointer-safety policy: ref-counted (RefPtr), checked
28/// (CheckedPtr), or retainable (RetainPtr/OSPtr).
29///
30/// It captures the family-specific "what is a safe/unsafe pointer" questions
31/// that are shared by the various RawPtrRef* checkers, independently of how
32/// each checker traverses the AST (call arguments, local variables, members,
33/// lambda captures, ...). This lets a single policy be defined once and reused
34/// across every traversal.
36public:
37 virtual ~PtrRefSafetyModel() = default;
38
39 /// \returns whether \p QT itself is an unsafe (smart-pointer-capable but not
40 /// managed) type, false if not, std::nullopt if inconclusive.
41 virtual std::optional<bool> isUnsafeType(QualType QT) const = 0;
42
43 /// \returns whether \p QT is a pointer/reference/view to an analyzed type,
44 /// false if not, std::nullopt if inconclusive. \p IgnoreARC requests that
45 /// Objective-C ARC be ignored when deciding retainability.
46 virtual std::optional<bool> isUnsafePtr(QualType QT,
47 bool IgnoreARC = false) const = 0;
48
49 /// \returns whether \p Record is a safe smart pointer for this policy.
50 virtual bool isSafePtr(const CXXRecordDecl *Record) const = 0;
51
52 /// \returns whether \p T is a safe smart pointer type for this policy.
53 virtual bool isSafePtrType(QualType T) const = 0;
54
55 /// \returns whether \p Name is the name of a safe smart pointer class for
56 /// this policy.
57 virtual bool isPtrType(const std::string &Name) const = 0;
58
59 /// \returns whether \p E is known to produce a safe value for this policy.
60 /// \p PtrIsLifetimeBoundToOrigin is whether the traversal that reached \p E
61 /// followed at least one [[clang::lifetimebound]] edge.
62 virtual bool isSafeExpr(const Expr *, bool PtrIsLifetimeBoundToOrigin) const {
63 return false;
64 }
65
66 /// \returns whether this policy checks for destruction of an object's
67 /// interior while the object itself stays alive (borrow checking), rather
68 /// than for deallocation of the object (the smart pointer policies).
69 virtual bool checksForInteriorDestruction() const { return false; }
70
71 /// \returns whether this policy checks assignment through indirection, such
72 /// as *out = _ or arr[0] = _. (Direct assignment to a named variable is
73 /// always checked.)
74 ///
75 /// FIXME: Make this flag true in all analyses and then remove it.
76 virtual bool recognizesIndirectStores() const { return false; }
77
78 /// \returns whether \p D refers to a declaration that is safe by construction
79 /// for this policy (e.g. immortal system-header globals).
80 virtual bool isSafeDecl(const Decl *, const SourceManager &) const {
81 return false;
82 }
83
84 /// \returns a human readable name for the safe type category, used in
85 /// diagnostics (e.g. "RefPtr-capable type").
86 virtual const char *typeName() const = 0;
87
88 /// Prints a phrase describing why the reported value is unsafe, completing a
89 /// sentence of the form "Local variable 'x' is a ". \p Origin is the
90 /// expression the value was traced back to, or null when the trace found
91 /// none. \p SinkType is the type of the reported location.
92 virtual void describeHazard(llvm::raw_ostream &Os, const Expr *,
93 QualType SinkType) const {
94 auto *VarType = SinkType.getTypePtr();
95 auto *DesugaredType = VarType->getUnqualifiedDesugaredType();
96 bool IsPtr = isa<PointerType, ObjCObjectPointerType>(DesugaredType);
97 Os << "raw " << (IsPtr ? "pointer" : "reference") << " to ";
98 Os << typeName() << " ";
99 printTypeName(Os, SinkType);
100 }
101
102 /// \returns the RetainTypeChecker backing this policy, or nullptr if the
103 /// policy does not track retain/OS types.
104 virtual RetainTypeChecker *retainTypeChecker() const { return nullptr; }
105};
106
107/// Applies the memory-management exemptions that hold for a variable, member,
108/// or lambda capture (but not for a call argument) before consulting \p Model:
109/// a __strong / __weak Objective-C storage location is memory managed and thus
110/// safe. \returns whether \p T is an unsafe pointer in such a storage context.
111std::optional<bool> isUnsafePtrForStorage(const PtrRefSafetyModel &Model,
112 QualType T, bool IgnoreARC = false);
113
114/// \returns a policy that treats ref-counted / checked pointers as safe.
115std::unique_ptr<PtrRefSafetyModel> makeRefPtrSafetyModel();
116
117/// \returns a policy that treats checked pointers as safe.
118std::unique_ptr<PtrRefSafetyModel> makeCheckedPtrSafetyModel();
119
120/// \returns a policy that treats RetainPtr / OSPtr as safe.
121std::unique_ptr<PtrRefSafetyModel> makeRetainPtrSafetyModel();
122
123/// \returns a policy that treats a loan on a CanBorrow object's interior as
124/// safe only when it is guarded by a Borrow<T>.
125std::unique_ptr<PtrRefSafetyModel> makeBorrowSafetyModel();
126
127} // namespace clang
128
129#endif
llvm::MachO::Record Record
Definition MachO.h:31
C Language Family Type Representation.
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
This represents one expression.
Definition Expr.h:113
Models one WebKit pointer-safety policy: ref-counted (RefPtr), checked (CheckedPtr),...
virtual bool isSafeExpr(const Expr *, bool PtrIsLifetimeBoundToOrigin) const
virtual ~PtrRefSafetyModel()=default
virtual std::optional< bool > isUnsafePtr(QualType QT, bool IgnoreARC=false) const =0
virtual bool checksForInteriorDestruction() const
virtual std::optional< bool > isUnsafeType(QualType QT) const =0
virtual RetainTypeChecker * retainTypeChecker() const
virtual bool recognizesIndirectStores() const
virtual bool isSafePtr(const CXXRecordDecl *Record) const =0
virtual const char * typeName() const =0
virtual bool isSafeDecl(const Decl *, const SourceManager &) const
virtual bool isSafePtrType(QualType T) const =0
virtual bool isPtrType(const std::string &Name) const =0
virtual void describeHazard(llvm::raw_ostream &Os, const Expr *, QualType SinkType) const
Prints a phrase describing why the reported value is unsafe, completing a sentence of the form "Local...
A (possibly-)qualified type.
Definition TypeBase.h:938
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8428
An inter-procedural analysis facility that detects CF types with the underlying pointer type.
This class handles loading and caching of source files into memory.
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
Definition Type.cpp:782
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
std::unique_ptr< PtrRefSafetyModel > makeBorrowSafetyModel()
std::unique_ptr< PtrRefSafetyModel > makeCheckedPtrSafetyModel()
std::optional< bool > isUnsafePtrForStorage(const PtrRefSafetyModel &Model, QualType T, bool IgnoreARC=false)
Applies the memory-management exemptions that hold for a variable, member, or lambda capture (but not...
const FunctionProtoType * T
void printTypeName(llvm::raw_ostream &Os, const QualType QT)
std::unique_ptr< PtrRefSafetyModel > makeRefPtrSafetyModel()
std::unique_ptr< PtrRefSafetyModel > makeRetainPtrSafetyModel()