Author: songruiwang Date: 2023-07-06T22:36:51+08:00 New Revision: b22a5d46179b0ec2d5350c078dc349f09177b9ed
URL: https://github.com/llvm/llvm-project/commit/b22a5d46179b0ec2d5350c078dc349f09177b9ed DIFF: https://github.com/llvm/llvm-project/commit/b22a5d46179b0ec2d5350c078dc349f09177b9ed.diff LOG: [analyzer] Fix false negative when pass implicit cast nil to nonnull We should look through implicit casts before determining the type of the arguments, and only allow explicit cast to _Nonnull to suppress warning ``` void foo(NSString *_Nonnull); foo((NSString * _Nonnull)nil); // no-warning id obj = nil; foo(obj); // should warning here (implicit cast id to NSString *_Nonnull) ``` Reviewed By: xazax.hun, steakhal Differential Revision: https://reviews.llvm.org/D154221 Added: Modified: clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp clang/test/Analysis/nullability-arc.mm clang/test/Analysis/nullability.mm Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp index 653a235b41a4fc..906f4e85a8e5b5 100644 --- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -798,7 +798,7 @@ void NullabilityChecker::checkPreCall(const CallEvent &Call, Nullability RequiredNullability = getNullabilityAnnotation(Param->getType()); Nullability ArgExprTypeLevelNullability = - getNullabilityAnnotation(ArgExpr->getType()); + getNullabilityAnnotation(lookThroughImplicitCasts(ArgExpr)->getType()); unsigned ParamIdx = Param->getFunctionScopeIndex() + 1; diff --git a/clang/test/Analysis/nullability-arc.mm b/clang/test/Analysis/nullability-arc.mm index 5c68dda42ed3ca..a149671bdb7300 100644 --- a/clang/test/Analysis/nullability-arc.mm +++ b/clang/test/Analysis/nullability-arc.mm @@ -3,9 +3,6 @@ // RUN: %clang_analyze_cc1 -w -analyzer-checker=core,nullability\ // RUN: -analyzer-output=text -verify %s -fobjc-arc -#if !__has_feature(objc_arc) -// expected-no-diagnostics -#endif #define nil ((id)0) @@ -24,16 +21,10 @@ @implementation Derived - (void)foo:(Param *)param { // FIXME: Why do we not emit the warning under ARC? [super foo:param]; -#if __has_feature(objc_arc) - // expected-warning@-2{{nil passed to a callee that requires a non-null 1st parameter}} - // expected-note@-3 {{nil passed to a callee that requires a non-null 1st parameter}} -#endif [self foo:nil]; -#if __has_feature(objc_arc) - // expected-note@-2{{Calling 'foo:'}} - // expected-note@-3{{Passing nil object reference via 1st parameter 'param'}} -#endif + // expected-warning@-1{{nil passed to a callee that requires a non-null 1st parameter}} + // expected-note@-2 {{nil passed to a callee that requires a non-null 1st parameter}} } @end diff --git a/clang/test/Analysis/nullability.mm b/clang/test/Analysis/nullability.mm index 5a702f86564a61..06bb9912296e32 100644 --- a/clang/test/Analysis/nullability.mm +++ b/clang/test/Analysis/nullability.mm @@ -69,6 +69,7 @@ - (void)takesUnspecified:(int *)p; void takesNonnull(Dummy *_Nonnull); void takesUnspecified(Dummy *); void takesNonnullBlock(void (^ _Nonnull)(void)); +void takesNonnullObject(NSObject *_Nonnull); Dummy *_Nullable returnsNullable(); Dummy *_Nonnull returnsNonnull(); @@ -275,6 +276,17 @@ void testObjCPropertyReadNullability() { return (Dummy * _Nonnull)0; // no-warning } +void testImplicitCastNilToNonnull() { + id obj = nil; + takesNonnullObject(obj); // expected-warning {{nil passed to a callee that requires a non-null 1st parameter}} +} + +void testImplicitCastNullableArgToNonnull(TestObject *_Nullable obj) { + if (!obj) { + takesNonnullObject(obj); // expected-warning {{nil passed to a callee that requires a non-null 1st parameter}} + } +} + void testIndirectCastNilToNonnullAndPass() { Dummy *p = (Dummy * _Nonnull)0; // FIXME: Ideally the cast above would suppress this warning. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits