Index: lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -340,8 +340,11 @@ if (!RegionVal) return false; - auto StoredVal = - State->getSVal(RegionVal->getRegion()).getAs(); + // There should have originally been a symbol. If it was a concrete value + // to begin with, the violation should have been handled immediately + // rather than delayed until constraints are updated. Why "symbol" rather than + // "region"? Because only symbolic regions can be null. + auto StoredVal = State->getSVal(*RegionVal).getAs(); if (!StoredVal) return false; Index: test/Analysis/nullability-arc.mm =================================================================== --- /dev/null +++ test/Analysis/nullability-arc.mm @@ -0,0 +1,37 @@ +// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,nullability -analyzer-output=text -verify %s +// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,nullability -analyzer-output=text -verify %s -fobjc-arc + +#if !__has_feature(objc_arc) +// expected-no-diagnostics +#endif + + +#define nil ((id)0) + +@interface Param +@end + +@interface Base +- (void)foo:(Param *_Nonnull)param; +@end + +@interface Derived : Base +@end + +@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 +} +@end + Index: test/Analysis/nullability.mm =================================================================== --- test/Analysis/nullability.mm +++ test/Analysis/nullability.mm @@ -1,5 +1,7 @@ // RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -DNOSYSTEMHEADERS=0 -verify %s // RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s +// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -DNOSYSTEMHEADERS=0 -verify %s -fobjc-arc +// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s -fobjc-arc #include "Inputs/system-header-simulator-for-nullability.h"