clang: lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
17#include
18
20
23}
24
26 const Expr *E, bool StopAtFirstRefCountedObj,
27 std::function<bool(const clang::Expr *, bool)> callback) {
28 while (E) {
29 if (auto *tempExpr = dyn_cast(E)) {
30 E = tempExpr->getSubExpr();
31 continue;
32 }
33 if (auto *tempExpr = dyn_cast(E)) {
34 E = tempExpr->getSubExpr();
35 continue;
36 }
37 if (auto *tempExpr = dyn_cast(E)) {
38 if (auto *C = tempExpr->getConstructor()) {
40 return callback(E, true);
41 break;
42 }
43 }
44 if (auto *POE = dyn_cast(E)) {
45 if (auto *RF = POE->getResultExpr()) {
46 E = RF;
47 continue;
48 }
49 }
50 if (auto *tempExpr = dyn_cast(E)) {
51 E = tempExpr->getSubExpr();
52 continue;
53 }
54 if (auto *Expr = dyn_cast(E)) {
56 callback) &&
58 callback);
59 }
60 if (auto *cast = dyn_cast(E)) {
61 if (StopAtFirstRefCountedObj) {
62 if (auto *ConversionFunc =
63 dyn_cast_or_null(cast->getConversionFunction())) {
65 return callback(E, true);
66 }
67 }
68
69
71 continue;
72 }
73 if (auto *call = dyn_cast(E)) {
74 if (auto *memberCall = dyn_cast(call)) {
75 if (auto *decl = memberCall->getMethodDecl()) {
77 if (IsGetterOfRefCt && *IsGetterOfRefCt) {
78 E = memberCall->getImplicitObjectArgument();
79 if (StopAtFirstRefCountedObj) {
80 return callback(E, true);
81 }
82 continue;
83 }
84 }
85 }
86
87 if (auto *operatorCall = dyn_cast(E)) {
88 if (operatorCall->getNumArgs() == 1) {
89 E = operatorCall->getArg(0);
90 continue;
91 }
92 }
93
94 if (auto *callee = call->getDirectCallee()) {
96 if (StopAtFirstRefCountedObj)
97 return callback(E, true);
98
99 E = call->getArg(0);
100 continue;
101 }
102
104 return callback(E, true);
105
107 return callback(E, true);
108
109 if (callee->isInStdNamespace() && safeGetName(callee) == "forward") {
110 E = call->getArg(0);
111 continue;
112 }
113
115 E = call->getArg(0);
116 continue;
117 }
118 }
119 }
120 if (auto *ObjCMsgExpr = dyn_cast(E)) {
121 if (auto *Method = ObjCMsgExpr->getMethodDecl()) {
123 return callback(E, true);
124 }
125 }
126 if (auto *unaryOp = dyn_cast(E)) {
127
128 E = unaryOp->getSubExpr();
129 continue;
130 }
131
132 break;
133 }
134
135 return callback(E, false);
136}
137
139 assert(E);
140 if (auto *Ref = dyn_cast(E)) {
141 if (auto *D = dyn_cast_or_null(Ref->getFoundDecl())) {
142 if (isa(D) || D->isLocalVarDecl())
143 return true;
144 }
145 }
147 return true;
148
149
150 return isa(E);
151}
152
154 if (auto *MCE = dyn_cast(E)) {
155 if (auto *Callee = MCE->getDirectCallee()) {
157 if (Name == "get" || Name == "ptr") {
158 auto *ThisArg = MCE->getImplicitObjectArgument();
159 E = ThisArg;
160 }
161 }
162 } else if (auto *OCE = dyn_cast(E)) {
163 if (OCE->getOperator() == OO_Star && OCE->getNumArgs() == 1)
164 E = OCE->getArg(0);
165 }
166 auto *ME = dyn_cast(E);
167 if (!ME)
168 return false;
169 auto *D = ME->getMemberDecl();
170 if ()
171 return false;
174}
175
178public:
180 for (const Stmt *Child : S->children()) {
181 if (Child && (Child))
182 return false;
183 }
184 return true;
185 }
186
189 RV = RV->IgnoreParenCasts();
190 if (isa(RV))
191 return true;
193 }
194 return false;
195 }
196};
197
199 auto *MCE = dyn_cast(E);
200 if (!MCE)
201 return false;
202 auto *Callee = MCE->getDirectCallee();
203 if (!Callee)
204 return false;
205 auto *Body = Callee->getBody();
206 if (!Body)
207 return false;
208 auto [CacheIt, IsNew] = Cache.insert(std::make_pair(Callee, false));
209 if (IsNew)
211 return CacheIt->second;
212}
213
214}
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Represents a C++ struct/union/class.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Decl - This represents one declaration (or definition), e.g.
bool isACallToEnsureFn(const Expr *E) const
bool VisitReturnStmt(const ReturnStmt *RS)
bool VisitStmt(const Stmt *S)
This represents one expression.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
RetTy Visit(PTR(Stmt) S, ParamTys... P)
Stmt - This represents one statement.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
bool isCtorOfSafePtr(const clang::FunctionDecl *F)
bool isPtrConversion(const FunctionDecl *F)
bool isCtorOfRefCounted(const clang::FunctionDecl *F)
bool isASafeCallArg(const Expr *E)
For E referring to a ref-countable/-counted pointer/reference we return whether it's a safe call argu...
bool isSingleton(const FunctionDecl *F)
bool isRefCounted(const CXXRecordDecl *R)
bool isOwnerPtrType(const clang::QualType T)
bool isSafePtrType(const clang::QualType T)
std::optional< bool > isGetterOfSafePtr(const CXXMethodDecl *M)
const FunctionProtoType * T
bool isSafePtr(clang::CXXRecordDecl *Decl)
bool tryToFindPtrOrigin(const Expr *E, bool StopAtFirstRefCountedObj, std::function< bool(const clang::Expr *, bool)> callback)
This function de-facto defines a set of transformations that we consider safe (in heuristical sense).
std::string safeGetName(const T *ASTNode)
bool isCtorOfCheckedPtr(const clang::FunctionDecl *F)
bool isCheckedPtr(const std::string &Name)
U cast(CodeGen::Address addr)
@ Class
The "class" keyword introduces the elaborated-type-specifier.
bool isConstOwnerPtrMemberExpr(const clang::Expr *E)