diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -767,7 +767,7 @@ 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 --- 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 @@ - (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 --- a/clang/test/Analysis/nullability.mm +++ b/clang/test/Analysis/nullability.mm @@ -69,6 +69,7 @@ void takesNonnull(Dummy *_Nonnull); void takesUnspecified(Dummy *); void takesNonnullBlock(void (^ _Nonnull)(void)); +void takesNonnullObject(NSObject *_Nonnull); Dummy *_Nullable returnsNullable(); Dummy *_Nonnull returnsNonnull(); @@ -264,6 +265,17 @@ 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.