xref: /llvm-project/clang/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp (revision 2301c5ab4dfda7e2f278971e183dc4b58990f18a)
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