Skip to content

Commit 7573ee1

Browse files
authored
Revert "[alpha.webkit.UnretainedCallArgsChecker] Add a checker for NS or CF type call arguments." (#130828)
Reverts #130729
1 parent d84755b commit 7573ee1

File tree

7 files changed

+8
-608
lines changed

7 files changed

+8
-608
lines changed

clang/docs/analyzer/checkers.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3642,12 +3642,6 @@ The goal of this rule is to make sure that lifetime of any dynamically allocated
36423642
36433643
The rules of when to use and not to use CheckedPtr / CheckedRef are same as alpha.webkit.UncountedCallArgsChecker for ref-counted objects.
36443644
3645-
alpha.webkit.UnretainedCallArgsChecker
3646-
""""""""""""""""""""""""""""""""""""""
3647-
The goal of this rule is to make sure that lifetime of any dynamically allocated NS or CF objects passed as a call argument keeps its memory region past the end of the call. This applies to call to any function, method, lambda, function pointer or functor. NS or CF objects aren't supposed to be allocated on stack so we check arguments for parameters of raw pointers and references to unretained types.
3648-
3649-
The rules of when to use and not to use RetainPtr are same as alpha.webkit.UncountedCallArgsChecker for ref-counted objects.
3650-
36513645
alpha.webkit.UncountedLocalVarsChecker
36523646
""""""""""""""""""""""""""""""""""""""
36533647
The goal of this rule is to make sure that any uncounted local variable is backed by a ref-counted object with lifetime that is strictly larger than the scope of the uncounted local variable. To be on the safe side we require the scope of an uncounted variable to be embedded in the scope of ref-counted object that backs it.

clang/include/clang/StaticAnalyzer/Checkers/Checkers.td

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,10 +1785,6 @@ def UncheckedCallArgsChecker : Checker<"UncheckedCallArgsChecker">,
17851785
HelpText<"Check unchecked call arguments.">,
17861786
Documentation<HasDocumentation>;
17871787

1788-
def UnretainedCallArgsChecker : Checker<"UnretainedCallArgsChecker">,
1789-
HelpText<"Check unretained call arguments.">,
1790-
Documentation<HasDocumentation>;
1791-
17921788
def UncountedLocalVarsChecker : Checker<"UncountedLocalVarsChecker">,
17931789
HelpText<"Check uncounted local variables.">,
17941790
Documentation<HasDocumentation>;

clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
#include "ASTUtils.h"
1010
#include "PtrTypesSemantics.h"
11-
#include "clang/AST/Attr.h"
1211
#include "clang/AST/CXXInheritance.h"
1312
#include "clang/AST/Decl.h"
1413
#include "clang/AST/DeclCXX.h"
@@ -29,15 +28,6 @@ bool tryToFindPtrOrigin(
2928
std::function<bool(const clang::QualType)> isSafePtrType,
3029
std::function<bool(const clang::Expr *, bool)> callback) {
3130
while (E) {
32-
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
33-
auto *ValDecl = DRE->getDecl();
34-
auto QT = ValDecl->getType();
35-
auto ValName = ValDecl->getName();
36-
if (ValDecl && (ValName.starts_with('k') || ValName.starts_with("_k")) &&
37-
QT.isConstQualified()) { // Treat constants such as kCF* as safe.
38-
return callback(E, true);
39-
}
40-
}
4131
if (auto *tempExpr = dyn_cast<MaterializeTemporaryExpr>(E)) {
4232
E = tempExpr->getSubExpr();
4333
continue;
@@ -67,10 +57,6 @@ bool tryToFindPtrOrigin(
6757
E = tempExpr->getSubExpr();
6858
continue;
6959
}
70-
if (auto *OpaqueValue = dyn_cast<OpaqueValueExpr>(E)) {
71-
E = OpaqueValue->getSourceExpr();
72-
continue;
73-
}
7460
if (auto *Expr = dyn_cast<ConditionalOperator>(E)) {
7561
return tryToFindPtrOrigin(Expr->getTrueExpr(), StopAtFirstRefCountedObj,
7662
isSafePtr, isSafePtrType, callback) &&
@@ -143,30 +129,14 @@ bool tryToFindPtrOrigin(
143129
E = call->getArg(0);
144130
continue;
145131
}
146-
147-
auto Name = safeGetName(callee);
148-
if (Name == "__builtin___CFStringMakeConstantString" ||
149-
Name == "NSClassFromString")
150-
return callback(E, true);
151132
}
152133
}
153134
if (auto *ObjCMsgExpr = dyn_cast<ObjCMessageExpr>(E)) {
154135
if (auto *Method = ObjCMsgExpr->getMethodDecl()) {
155136
if (isSafePtrType(Method->getReturnType()))
156137
return callback(E, true);
157138
}
158-
auto Selector = ObjCMsgExpr->getSelector();
159-
auto NameForFirstSlot = Selector.getNameForSlot(0);
160-
if ((NameForFirstSlot == "class" || NameForFirstSlot == "superclass") &&
161-
!Selector.getNumArgs())
162-
return callback(E, true);
163139
}
164-
if (auto *ObjCDict = dyn_cast<ObjCDictionaryLiteral>(E))
165-
return callback(ObjCDict, true);
166-
if (auto *ObjCArray = dyn_cast<ObjCArrayLiteral>(E))
167-
return callback(ObjCArray, true);
168-
if (auto *ObjCStr = dyn_cast<ObjCStringLiteral>(E))
169-
return callback(ObjCStr, true);
170140
if (auto *unaryOp = dyn_cast<UnaryOperator>(E)) {
171141
// FIXME: Currently accepts ANY unary operator. Is it OK?
172142
E = unaryOp->getSubExpr();
@@ -186,14 +156,6 @@ bool isASafeCallArg(const Expr *E) {
186156
if (auto *D = dyn_cast_or_null<VarDecl>(FoundDecl)) {
187157
if (isa<ParmVarDecl>(D) || D->isLocalVarDecl())
188158
return true;
189-
if (auto *ImplicitP = dyn_cast<ImplicitParamDecl>(D)) {
190-
auto Kind = ImplicitP->getParameterKind();
191-
if (Kind == ImplicitParamKind::ObjCSelf ||
192-
Kind == ImplicitParamKind::ObjCCmd ||
193-
Kind == ImplicitParamKind::CXXThis ||
194-
Kind == ImplicitParamKind::CXXVTT)
195-
return true;
196-
}
197159
} else if (auto *BD = dyn_cast_or_null<BindingDecl>(FoundDecl)) {
198160
VarDecl *VD = BD->getHoldingVar();
199161
if (VD && (isa<ParmVarDecl>(VD) || VD->isLocalVarDecl()))

clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,7 @@ std::optional<bool> isGetterOfSafePtr(const CXXMethodDecl *M) {
372372
if (auto *maybeRefToRawOperator = dyn_cast<CXXConversionDecl>(M)) {
373373
auto QT = maybeRefToRawOperator->getConversionType();
374374
auto *T = QT.getTypePtrOrNull();
375-
return T && (T->isPointerType() || T->isReferenceType() ||
376-
T->isObjCObjectPointerType());
375+
return T && (T->isPointerType() || T->isReferenceType());
377376
}
378377
}
379378
}
@@ -416,8 +415,7 @@ bool isPtrConversion(const FunctionDecl *F) {
416415
if (FunctionName == "getPtr" || FunctionName == "WeakPtr" ||
417416
FunctionName == "dynamicDowncast" || FunctionName == "downcast" ||
418417
FunctionName == "checkedDowncast" ||
419-
FunctionName == "uncheckedDowncast" || FunctionName == "bitwise_cast" ||
420-
FunctionName == "bridge_cast")
418+
FunctionName == "uncheckedDowncast" || FunctionName == "bitwise_cast")
421419
return true;
422420

423421
return false;

clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp

Lines changed: 6 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "clang/AST/Decl.h"
1414
#include "clang/AST/DeclCXX.h"
1515
#include "clang/AST/DynamicRecursiveASTVisitor.h"
16-
#include "clang/Analysis/DomainSpecific/CocoaConventions.h"
1716
#include "clang/Basic/SourceLocation.h"
1817
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
1918
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
@@ -36,9 +35,6 @@ class RawPtrRefCallArgsChecker
3635
TrivialFunctionAnalysis TFA;
3736
EnsureFunctionAnalysis EFA;
3837

39-
protected:
40-
mutable std::optional<RetainTypeChecker> RTC;
41-
4238
public:
4339
RawPtrRefCallArgsChecker(const char *description)
4440
: Bug(this, description, "WebKit coding guidelines") {}
@@ -84,22 +80,9 @@ class RawPtrRefCallArgsChecker
8480
Checker->visitCallExpr(CE, DeclWithIssue);
8581
return true;
8682
}
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-
}
9883
};
9984

10085
LocalVisitor visitor(this);
101-
if (RTC)
102-
RTC->visitTranslationUnitDecl(TUD);
10386
visitor.TraverseDecl(const_cast<TranslationUnitDecl *>(TUD));
10487
}
10588

@@ -139,7 +122,7 @@ class RawPtrRefCallArgsChecker
139122
// if ((*P)->hasAttr<SafeRefCntblRawPtrAttr>())
140123
// continue;
141124

142-
QualType ArgType = (*P)->getType();
125+
QualType ArgType = (*P)->getType().getCanonicalType();
143126
// FIXME: more complex types (arrays, references to raw pointers, etc)
144127
std::optional<bool> IsUncounted = isUnsafePtr(ArgType);
145128
if (!IsUncounted || !(*IsUncounted))
@@ -155,58 +138,6 @@ class RawPtrRefCallArgsChecker
155138

156139
reportBug(Arg, *P, D);
157140
}
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);
210141
}
211142
}
212143

@@ -227,8 +158,6 @@ class RawPtrRefCallArgsChecker
227158
// foo(NULL)
228159
return true;
229160
}
230-
if (isa<ObjCStringLiteral>(ArgOrigin))
231-
return true;
232161
if (isASafeCallArg(ArgOrigin))
233162
return true;
234163
if (EFA.isACallToEnsureFn(ArgOrigin))
@@ -283,7 +212,7 @@ class RawPtrRefCallArgsChecker
283212
overloadedOperatorType == OO_PipePipe)
284213
return true;
285214

286-
if (isCtorOfSafePtr(Callee))
215+
if (isCtorOfRefCounted(Callee))
287216
return true;
288217

289218
auto name = safeGetName(Callee);
@@ -348,10 +277,9 @@ class RawPtrRefCallArgsChecker
348277
}
349278
Os << " is " << ptrKind() << " and unsafe.";
350279

351-
bool usesDefaultArgValue = isa<CXXDefaultArgExpr>(CallArg) && Param;
352280
const SourceLocation SrcLocToReport =
353-
usesDefaultArgValue ? Param->getDefaultArg()->getExprLoc()
354-
: CallArg->getSourceRange().getBegin();
281+
isa<CXXDefaultArgExpr>(CallArg) ? Param->getDefaultArg()->getExprLoc()
282+
: CallArg->getSourceRange().getBegin();
355283

356284
PathDiagnosticLocation BSLoc(SrcLocToReport, BR->getSourceManager());
357285
auto Report = std::make_unique<BasicBugReport>(Bug, Os.str(), BSLoc);
@@ -376,23 +304,6 @@ class RawPtrRefCallArgsChecker
376304
Report->setDeclWithIssue(DeclWithIssue);
377305
BR->emitReport(std::move(Report));
378306
}
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-
}
396307
};
397308

398309
class UncountedCallArgsChecker final : public RawPtrRefCallArgsChecker {
@@ -406,7 +317,7 @@ class UncountedCallArgsChecker final : public RawPtrRefCallArgsChecker {
406317
}
407318

408319
std::optional<bool> isUnsafePtr(QualType QT) const final {
409-
return isUncountedPtr(QT.getCanonicalType());
320+
return isUncountedPtr(QT);
410321
}
411322

412323
bool isSafePtr(const CXXRecordDecl *Record) const final {
@@ -431,7 +342,7 @@ class UncheckedCallArgsChecker final : public RawPtrRefCallArgsChecker {
431342
}
432343

433344
std::optional<bool> isUnsafePtr(QualType QT) const final {
434-
return isUncheckedPtr(QT.getCanonicalType());
345+
return isUncheckedPtr(QT);
435346
}
436347

437348
bool isSafePtr(const CXXRecordDecl *Record) const final {
@@ -445,33 +356,6 @@ class UncheckedCallArgsChecker final : public RawPtrRefCallArgsChecker {
445356
const char *ptrKind() const final { return "unchecked"; }
446357
};
447358

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-
475359
} // namespace
476360

477361
void ento::registerUncountedCallArgsChecker(CheckerManager &Mgr) {
@@ -489,11 +373,3 @@ void ento::registerUncheckedCallArgsChecker(CheckerManager &Mgr) {
489373
bool ento::shouldRegisterUncheckedCallArgsChecker(const CheckerManager &) {
490374
return true;
491375
}
492-
493-
void ento::registerUnretainedCallArgsChecker(CheckerManager &Mgr) {
494-
Mgr.registerChecker<UnretainedCallArgsChecker>();
495-
}
496-
497-
bool ento::shouldRegisterUnretainedCallArgsChecker(const CheckerManager &) {
498-
return true;
499-
}

clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)