1 //== TrustNonnullChecker.cpp - Checker for trusting annotations -*- C++ -*--==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This checker adds an assumption that methods annotated with _Nonnull 11 // which come from system headers actually return a non-null pointer. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "ClangSACheckers.h" 16 #include "clang/StaticAnalyzer/Core/Checker.h" 17 #include "clang/StaticAnalyzer/Core/CheckerManager.h" 18 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 19 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h" 20 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 21 22 using namespace clang; 23 using namespace ento; 24 25 namespace { 26 27 class TrustNonnullChecker : public Checker<check::PostCall> { 28 public: 29 void checkPostCall(const CallEvent &Call, CheckerContext &C) const { 30 // Only trust annotations for system headers for non-protocols. 31 if (!Call.isInSystemHeader()) 32 return; 33 34 QualType RetType = Call.getResultType(); 35 if (!RetType->isAnyPointerType()) 36 return; 37 38 ProgramStateRef State = C.getState(); 39 if (getNullabilityAnnotation(RetType) == Nullability::Nonnull) 40 if (auto L = Call.getReturnValue().getAs<Loc>()) 41 State = State->assume(*L, /*Assumption=*/true); 42 43 C.addTransition(State); 44 } 45 }; 46 47 } // end empty namespace 48 49 50 void ento::registerTrustNonnullChecker(CheckerManager &Mgr) { 51 Mgr.registerChecker<TrustNonnullChecker>(); 52 } 53