13
13
#include " clang/AST/Decl.h"
14
14
#include " clang/AST/DeclCXX.h"
15
15
#include " clang/AST/DynamicRecursiveASTVisitor.h"
16
- #include " clang/Analysis/DomainSpecific/CocoaConventions.h"
17
16
#include " clang/Basic/SourceLocation.h"
18
17
#include " clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
19
18
#include " clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
@@ -36,9 +35,6 @@ class RawPtrRefCallArgsChecker
36
35
TrivialFunctionAnalysis TFA;
37
36
EnsureFunctionAnalysis EFA;
38
37
39
- protected:
40
- mutable std::optional<RetainTypeChecker> RTC;
41
-
42
38
public:
43
39
RawPtrRefCallArgsChecker (const char *description)
44
40
: Bug(this , description, " WebKit coding guidelines" ) {}
@@ -84,22 +80,9 @@ class RawPtrRefCallArgsChecker
84
80
Checker->visitCallExpr (CE, DeclWithIssue);
85
81
return true ;
86
82
}
87
-
88
- bool VisitTypedefDecl (TypedefDecl *TD) override {
89
- if (Checker->RTC )
90
- Checker->RTC ->visitTypedef (TD);
91
- return true ;
92
- }
93
-
94
- bool VisitObjCMessageExpr (ObjCMessageExpr *ObjCMsgExpr) override {
95
- Checker->visitObjCMessageExpr (ObjCMsgExpr, DeclWithIssue);
96
- return true ;
97
- }
98
83
};
99
84
100
85
LocalVisitor visitor (this );
101
- if (RTC)
102
- RTC->visitTranslationUnitDecl (TUD);
103
86
visitor.TraverseDecl (const_cast <TranslationUnitDecl *>(TUD));
104
87
}
105
88
@@ -139,7 +122,7 @@ class RawPtrRefCallArgsChecker
139
122
// if ((*P)->hasAttr<SafeRefCntblRawPtrAttr>())
140
123
// continue;
141
124
142
- QualType ArgType = (*P)->getType ();
125
+ QualType ArgType = (*P)->getType (). getCanonicalType () ;
143
126
// FIXME: more complex types (arrays, references to raw pointers, etc)
144
127
std::optional<bool > IsUncounted = isUnsafePtr (ArgType);
145
128
if (!IsUncounted || !(*IsUncounted))
@@ -155,58 +138,6 @@ class RawPtrRefCallArgsChecker
155
138
156
139
reportBug (Arg, *P, D);
157
140
}
158
- for (; ArgIdx < CE->getNumArgs (); ++ArgIdx) {
159
- const auto *Arg = CE->getArg (ArgIdx);
160
- auto ArgType = Arg->getType ();
161
- std::optional<bool > IsUncounted = isUnsafePtr (ArgType);
162
- if (!IsUncounted || !(*IsUncounted))
163
- continue ;
164
-
165
- if (auto *defaultArg = dyn_cast<CXXDefaultArgExpr>(Arg))
166
- Arg = defaultArg->getExpr ();
167
-
168
- if (isPtrOriginSafe (Arg))
169
- continue ;
170
-
171
- reportBug (Arg, nullptr , D);
172
- }
173
- }
174
- }
175
-
176
- void visitObjCMessageExpr (const ObjCMessageExpr *E, const Decl *D) const {
177
- if (BR->getSourceManager ().isInSystemHeader (E->getExprLoc ()))
178
- return ;
179
-
180
- auto Selector = E->getSelector ();
181
- if (auto *Receiver = E->getInstanceReceiver ()->IgnoreParenCasts ()) {
182
- std::optional<bool > IsUnsafe = isUnsafePtr (E->getReceiverType ());
183
- if (IsUnsafe && *IsUnsafe && !isPtrOriginSafe (Receiver)) {
184
- if (auto *InnerMsg = dyn_cast<ObjCMessageExpr>(Receiver)) {
185
- auto InnerSelector = InnerMsg->getSelector ();
186
- if (InnerSelector.getNameForSlot (0 ) == " alloc" &&
187
- Selector.getNameForSlot (0 ).starts_with (" init" ))
188
- return ;
189
- }
190
- reportBugOnReceiver (Receiver, D);
191
- }
192
- }
193
-
194
- auto *MethodDecl = E->getMethodDecl ();
195
- if (!MethodDecl)
196
- return ;
197
-
198
- auto ArgCount = E->getNumArgs ();
199
- for (unsigned i = 0 ; i < ArgCount; ++i) {
200
- auto *Arg = E->getArg (i);
201
- bool hasParam = i < MethodDecl->param_size ();
202
- auto *Param = hasParam ? MethodDecl->getParamDecl (i) : nullptr ;
203
- auto ArgType = Arg->getType ();
204
- std::optional<bool > IsUnsafe = isUnsafePtr (ArgType);
205
- if (!IsUnsafe || !(*IsUnsafe))
206
- continue ;
207
- if (isPtrOriginSafe (Arg))
208
- continue ;
209
- reportBug (Arg, Param, D);
210
141
}
211
142
}
212
143
@@ -227,8 +158,6 @@ class RawPtrRefCallArgsChecker
227
158
// foo(NULL)
228
159
return true ;
229
160
}
230
- if (isa<ObjCStringLiteral>(ArgOrigin))
231
- return true ;
232
161
if (isASafeCallArg (ArgOrigin))
233
162
return true ;
234
163
if (EFA.isACallToEnsureFn (ArgOrigin))
@@ -283,7 +212,7 @@ class RawPtrRefCallArgsChecker
283
212
overloadedOperatorType == OO_PipePipe)
284
213
return true ;
285
214
286
- if (isCtorOfSafePtr (Callee))
215
+ if (isCtorOfRefCounted (Callee))
287
216
return true ;
288
217
289
218
auto name = safeGetName (Callee);
@@ -348,10 +277,9 @@ class RawPtrRefCallArgsChecker
348
277
}
349
278
Os << " is " << ptrKind () << " and unsafe." ;
350
279
351
- bool usesDefaultArgValue = isa<CXXDefaultArgExpr>(CallArg) && Param;
352
280
const SourceLocation SrcLocToReport =
353
- usesDefaultArgValue ? Param->getDefaultArg ()->getExprLoc ()
354
- : CallArg->getSourceRange ().getBegin ();
281
+ isa<CXXDefaultArgExpr>(CallArg) ? Param->getDefaultArg ()->getExprLoc ()
282
+ : CallArg->getSourceRange ().getBegin ();
355
283
356
284
PathDiagnosticLocation BSLoc (SrcLocToReport, BR->getSourceManager ());
357
285
auto Report = std::make_unique<BasicBugReport>(Bug, Os.str (), BSLoc);
@@ -376,23 +304,6 @@ class RawPtrRefCallArgsChecker
376
304
Report->setDeclWithIssue (DeclWithIssue);
377
305
BR->emitReport (std::move (Report));
378
306
}
379
-
380
- void reportBugOnReceiver (const Expr *CallArg,
381
- const Decl *DeclWithIssue) const {
382
- assert (CallArg);
383
-
384
- const SourceLocation SrcLocToReport = CallArg->getSourceRange ().getBegin ();
385
-
386
- SmallString<100 > Buf;
387
- llvm::raw_svector_ostream Os (Buf);
388
- Os << " Reciever is " << ptrKind () << " and unsafe." ;
389
-
390
- PathDiagnosticLocation BSLoc (SrcLocToReport, BR->getSourceManager ());
391
- auto Report = std::make_unique<BasicBugReport>(Bug, Os.str (), BSLoc);
392
- Report->addRange (CallArg->getSourceRange ());
393
- Report->setDeclWithIssue (DeclWithIssue);
394
- BR->emitReport (std::move (Report));
395
- }
396
307
};
397
308
398
309
class UncountedCallArgsChecker final : public RawPtrRefCallArgsChecker {
@@ -406,7 +317,7 @@ class UncountedCallArgsChecker final : public RawPtrRefCallArgsChecker {
406
317
}
407
318
408
319
std::optional<bool > isUnsafePtr (QualType QT) const final {
409
- return isUncountedPtr (QT. getCanonicalType () );
320
+ return isUncountedPtr (QT);
410
321
}
411
322
412
323
bool isSafePtr (const CXXRecordDecl *Record) const final {
@@ -431,7 +342,7 @@ class UncheckedCallArgsChecker final : public RawPtrRefCallArgsChecker {
431
342
}
432
343
433
344
std::optional<bool > isUnsafePtr (QualType QT) const final {
434
- return isUncheckedPtr (QT. getCanonicalType () );
345
+ return isUncheckedPtr (QT);
435
346
}
436
347
437
348
bool isSafePtr (const CXXRecordDecl *Record) const final {
@@ -445,33 +356,6 @@ class UncheckedCallArgsChecker final : public RawPtrRefCallArgsChecker {
445
356
const char *ptrKind () const final { return " unchecked" ; }
446
357
};
447
358
448
- class UnretainedCallArgsChecker final : public RawPtrRefCallArgsChecker {
449
- public:
450
- UnretainedCallArgsChecker ()
451
- : RawPtrRefCallArgsChecker(" Unretained call argument for a raw "
452
- " pointer/reference parameter" ) {
453
- RTC = RetainTypeChecker ();
454
- }
455
-
456
- std::optional<bool > isUnsafeType (QualType QT) const final {
457
- return RTC->isUnretained (QT);
458
- }
459
-
460
- std::optional<bool > isUnsafePtr (QualType QT) const final {
461
- return RTC->isUnretained (QT);
462
- }
463
-
464
- bool isSafePtr (const CXXRecordDecl *Record) const final {
465
- return isRetainPtr (Record);
466
- }
467
-
468
- bool isSafePtrType (const QualType type) const final {
469
- return isRetainPtrType (type);
470
- }
471
-
472
- const char *ptrKind () const final { return " unretained" ; }
473
- };
474
-
475
359
} // namespace
476
360
477
361
void ento::registerUncountedCallArgsChecker (CheckerManager &Mgr) {
@@ -489,11 +373,3 @@ void ento::registerUncheckedCallArgsChecker(CheckerManager &Mgr) {
489
373
bool ento::shouldRegisterUncheckedCallArgsChecker (const CheckerManager &) {
490
374
return true ;
491
375
}
492
-
493
- void ento::registerUnretainedCallArgsChecker (CheckerManager &Mgr) {
494
- Mgr.registerChecker <UnretainedCallArgsChecker>();
495
- }
496
-
497
- bool ento::shouldRegisterUnretainedCallArgsChecker (const CheckerManager &) {
498
- return true ;
499
- }
0 commit comments