r262763 - [analyzer] Nullability: add option to not report on calls to system headers.

Devin Coughlin via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 4 17:32:44 PST 2016


Author: dcoughlin
Date: Fri Mar  4 19:32:43 2016
New Revision: 262763

URL: http://llvm.org/viewvc/llvm-project?rev=262763&view=rev
Log:
[analyzer] Nullability: add option to not report on calls to system headers.

Add an -analyzer-config 'nullability:NoDiagnoseCallsToSystemHeaders' option to
the nullability checker. When enabled, this option causes the analyzer to not
report about passing null/nullable values to functions and methods declared
in system headers.

This option is motivated by the observation that large projects may have many
nullability warnings. These projects may find warnings about nullability
annotations that they have explicitly added themselves higher priority to fix
than warnings on calls to system libraries.

Added:
    cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-nullability.h
Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
    cfe/trunk/test/Analysis/nullability.mm
    cfe/trunk/test/Analysis/nullability_nullonly.mm

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp?rev=262763&r1=262762&r2=262763&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp Fri Mar  4 19:32:43 2016
@@ -100,6 +100,14 @@ class NullabilityChecker
   mutable std::unique_ptr<BugType> BT;
 
 public:
+  // If true, the checker will not diagnose nullabilility issues for calls
+  // to system headers. This option is motivated by the observation that large
+  // projects may have many nullability warnings. These projects may
+  // find warnings about nullability annotations that they have explicitly
+  // added themselves higher priority to fix than warnings on calls to system
+  // libraries.
+  DefaultBool NoDiagnoseCallsToSystemHeaders;
+
   void checkBind(SVal L, SVal V, const Stmt *S, CheckerContext &C) const;
   void checkPostStmt(const ExplicitCastExpr *CE, CheckerContext &C) const;
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
@@ -191,6 +199,15 @@ private:
   /// to the wrapped region. Otherwise it will return a nullptr.
   const SymbolicRegion *getTrackRegion(SVal Val,
                                        bool CheckSuperRegion = false) const;
+
+  /// Returns true if the call is diagnosable in the currrent analyzer
+  /// configuration.
+  bool isDiagnosableCall(const CallEvent &Call) const {
+    if (NoDiagnoseCallsToSystemHeaders && Call.isInSystemHeader())
+      return false;
+
+    return true;
+  }
 };
 
 class NullabilityState {
@@ -620,7 +637,8 @@ void NullabilityChecker::checkPreCall(co
 
     if (Filter.CheckNullPassedToNonnull && Nullness == NullConstraint::IsNull &&
         ArgExprTypeLevelNullability != Nullability::Nonnull &&
-        RequiredNullability == Nullability::Nonnull) {
+        RequiredNullability == Nullability::Nonnull &&
+        isDiagnosableCall(Call)) {
       ExplodedNode *N = C.generateErrorNode(State);
       if (!N)
         return;
@@ -647,7 +665,8 @@ void NullabilityChecker::checkPreCall(co
         continue;
 
       if (Filter.CheckNullablePassedToNonnull &&
-          RequiredNullability == Nullability::Nonnull) {
+          RequiredNullability == Nullability::Nonnull &&
+          isDiagnosableCall(Call)) {
         ExplodedNode *N = C.addTransition(State);
         SmallString<256> SBuf;
         llvm::raw_svector_ostream OS(SBuf);
@@ -1106,6 +1125,10 @@ void NullabilityChecker::printState(raw_
     checker->Filter.Check##name = true;                                        \
     checker->Filter.CheckName##name = mgr.getCurrentCheckName();               \
     checker->NeedTracking = checker->NeedTracking || trackingRequired;         \
+    checker->NoDiagnoseCallsToSystemHeaders =                                  \
+        checker->NoDiagnoseCallsToSystemHeaders ||                             \
+        mgr.getAnalyzerOptions().getBooleanOption(                             \
+                      "NoDiagnoseCallsToSystemHeaders", false, checker, true); \
   }
 
 // The checks are likely to be turned on by default and it is possible to do

Added: cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-nullability.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-nullability.h?rev=262763&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-nullability.h (added)
+++ cfe/trunk/test/Analysis/Inputs/system-header-simulator-for-nullability.h Fri Mar  4 19:32:43 2016
@@ -0,0 +1,42 @@
+#pragma clang system_header
+
+#define nil 0
+#define BOOL int
+
+#define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
+#define NS_ASSUME_NONNULL_END   _Pragma("clang assume_nonnull end")
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef struct _NSZone NSZone;
+
+ at protocol NSObject
++ (id)alloc;
+- (id)init;
+ at end
+
+ at protocol NSCopying
+- (id)copyWithZone:(nullable NSZone *)zone;
+ at end
+
+ at protocol NSMutableCopying
+- (id)mutableCopyWithZone:(nullable NSZone *)zone;
+ at end
+
+__attribute__((objc_root_class))
+ at interface
+NSObject<NSObject>
+ at end
+
+ at interface NSString : NSObject<NSCopying>
+- (BOOL)isEqualToString : (NSString *)aString;
+- (NSString *)stringByAppendingString:(NSString *)aString;
+ at end
+
+void NSSystemFunctionTakingNonnull(NSString *s);
+
+ at interface NSSystemClass : NSObject
+- (void) takesNonnull:(NSString *)s;
+ at end
+
+NS_ASSUME_NONNULL_END

Modified: cfe/trunk/test/Analysis/nullability.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nullability.mm?rev=262763&r1=262762&r2=262763&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/nullability.mm (original)
+++ cfe/trunk/test/Analysis/nullability.mm Fri Mar  4 19:32:43 2016
@@ -1,38 +1,7 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability -verify %s
+// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability -DNOSYSTEMHEADERS=0 -verify %s
+// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
 
-#define nil 0
-#define BOOL int
-
-#define NS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
-#define NS_ASSUME_NONNULL_END   _Pragma("clang assume_nonnull end")
-
-typedef struct _NSZone NSZone;
-
- at protocol NSObject
-+ (id)alloc;
-- (id)init;
- at end
-
-NS_ASSUME_NONNULL_BEGIN
- at protocol NSCopying
-- (id)copyWithZone:(nullable NSZone *)zone;
-
- at end
-
- at protocol NSMutableCopying
-- (id)mutableCopyWithZone:(nullable NSZone *)zone;
- at end
-NS_ASSUME_NONNULL_END
-
-__attribute__((objc_root_class))
- at interface
-NSObject<NSObject>
- at end
-
- at interface NSString : NSObject<NSCopying>
-- (BOOL)isEqualToString : (NSString *_Nonnull)aString;
-- (NSString *)stringByAppendingString:(NSString *_Nonnull)aString;
- at end
+#include "Inputs/system-header-simulator-for-nullability.h"
 
 @interface TestObject : NSObject
 - (int *_Nonnull)returnsNonnull;
@@ -419,3 +388,24 @@ Dummy *_Nonnull testDefensiveInlineCheck
   return newInstance;
 }
 @end
+
+NSString * _Nullable returnsNullableString();
+
+void callFunctionInSystemHeader() {
+  NSString *s = returnsNullableString();
+
+  NSSystemFunctionTakingNonnull(s);
+  #if !NOSYSTEMHEADERS
+  // expected-warning at -2{{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
+  #endif
+}
+
+void callMethodInSystemHeader() {
+  NSString *s = returnsNullableString();
+
+  NSSystemClass *sc = [[NSSystemClass alloc] init];
+  [sc takesNonnull:s];
+  #if !NOSYSTEMHEADERS
+  // expected-warning at -2{{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
+  #endif
+}

Modified: cfe/trunk/test/Analysis/nullability_nullonly.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nullability_nullonly.mm?rev=262763&r1=262762&r2=262763&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/nullability_nullonly.mm (original)
+++ cfe/trunk/test/Analysis/nullability_nullonly.mm Fri Mar  4 19:32:43 2016
@@ -1,20 +1,7 @@
-// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -verify %s
+// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -DNOSYSTEMHEADERS=0 -verify %s
+// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
 
-#define nil 0
-#define BOOL int
-
- at protocol NSObject
-+ (id)alloc;
-- (id)init;
- at end
-
- at protocol NSCopying
- at end
-
-__attribute__((objc_root_class))
- at interface
-NSObject<NSObject>
- at end
+#include "Inputs/system-header-simulator-for-nullability.h"
 
 int getRandom();
 
@@ -159,3 +146,25 @@ TestObject * _Nonnull returnsNilObjCInst
     return p; // no-warning
 }
 @end
+
+
+void callFunctionInSystemHeader() {
+  NSString *s;
+  s = nil;
+
+  NSSystemFunctionTakingNonnull(s);
+  #if !NOSYSTEMHEADERS
+  // expected-warning at -2{{Null passed to a callee that requires a non-null 1st parameter}}
+  #endif
+}
+
+void callMethodInSystemHeader() {
+  NSString *s;
+  s = nil;
+
+  NSSystemClass *sc = [[NSSystemClass alloc] init];
+  [sc takesNonnull:s];
+  #if !NOSYSTEMHEADERS
+  // expected-warning at -2{{Null passed to a callee that requires a non-null 1st parameter}}
+  #endif
+}




More information about the cfe-commits mailing list