diff options
| author | Devin Coughlin <dcoughlin@apple.com> | 2016-01-28 22:23:34 +0000 |
|---|---|---|
| committer | Devin Coughlin <dcoughlin@apple.com> | 2016-01-28 22:23:34 +0000 |
| commit | de21767a4d127293fe0ce945225f5851e80fa058 (patch) | |
| tree | 572a96be78e8c2085fa401d6f8f9e74ebb12c99c /clang/lib | |
| parent | c33088f41ec25e1b89af1e1a3f51f7ce998ca2d5 (diff) | |
| download | bcm5719-llvm-de21767a4d127293fe0ce945225f5851e80fa058.tar.gz bcm5719-llvm-de21767a4d127293fe0ce945225f5851e80fa058.zip | |
[analyzer] Suppress nullability warnings in copy, mutableCopy, and init families.
There are multiple, common idioms of defensive nil-checks in copy,
mutableCopy, and init methods in ObjC. The analyzer doesn't currently have the
capability to distinguish these idioms from true positives, so suppress all
warnings about returns in those families. This is a pretty blunt suppression
that we should improve later.
rdar://problem/24395811
llvm-svn: 259099
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp index 079a71e0174..ce6fde28b01 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -510,23 +510,22 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S, if (!RetSVal) return; - bool IsReturnSelfInObjCInit = false; + bool InSuppressedMethodFamily = false; QualType RequiredRetType; AnalysisDeclContext *DeclCtxt = C.getLocationContext()->getAnalysisDeclContext(); const Decl *D = DeclCtxt->getDecl(); if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) { + // HACK: This is a big hammer to avoid warning when there are defensive + // nil checks in -init and -copy methods. We should add more sophisticated + // logic here to suppress on common defensive idioms but still + // warn when there is a likely problem. + ObjCMethodFamily Family = MD->getMethodFamily(); + if (OMF_init == Family || OMF_copy == Family || OMF_mutableCopy == Family) + InSuppressedMethodFamily = true; + RequiredRetType = MD->getReturnType(); - // Suppress diagnostics for returns of nil that are syntactic returns of - // self in ObjC initializers. This avoids warning under the common idiom of - // a defensive check of the result of a call to super: - // if (self = [super init]) { - // ... - // } - // return self; // no-warning - IsReturnSelfInObjCInit = (MD->getMethodFamily() == OMF_init) && - isReturnSelf(S, C); } else if (auto *FD = dyn_cast<FunctionDecl>(D)) { RequiredRetType = FD->getReturnType(); } else { @@ -549,7 +548,7 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S, Nullness == NullConstraint::IsNull && RetExprTypeLevelNullability != Nullability::Nonnull && RequiredNullability == Nullability::Nonnull && - !IsReturnSelfInObjCInit) { + !InSuppressedMethodFamily) { static CheckerProgramPointTag Tag(this, "NullReturnedFromNonnull"); ExplodedNode *N = C.generateErrorNode(State, &Tag); if (!N) |

