1*faabdfcfSRashmi Mudduluru //== TrustReturnsNonnullChecker.cpp -- API nullability modeling -*- C++ -*--==// 2*faabdfcfSRashmi Mudduluru // 3*faabdfcfSRashmi Mudduluru // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*faabdfcfSRashmi Mudduluru // See https://llvm.org/LICENSE.txt for license information. 5*faabdfcfSRashmi Mudduluru // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*faabdfcfSRashmi Mudduluru // 7*faabdfcfSRashmi Mudduluru //===----------------------------------------------------------------------===// 8*faabdfcfSRashmi Mudduluru // 9*faabdfcfSRashmi Mudduluru // This checker adds nullability-related assumptions to methods annotated with 10*faabdfcfSRashmi Mudduluru // returns_nonnull attribute. 11*faabdfcfSRashmi Mudduluru // 12*faabdfcfSRashmi Mudduluru //===----------------------------------------------------------------------===// 13*faabdfcfSRashmi Mudduluru 14*faabdfcfSRashmi Mudduluru #include "clang/AST/Attr.h" 15*faabdfcfSRashmi Mudduluru #include "clang/AST/Decl.h" 16*faabdfcfSRashmi Mudduluru #include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" 17*faabdfcfSRashmi Mudduluru #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 18*faabdfcfSRashmi Mudduluru #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" 19*faabdfcfSRashmi Mudduluru 20*faabdfcfSRashmi Mudduluru using namespace clang; 21*faabdfcfSRashmi Mudduluru using namespace ento; 22*faabdfcfSRashmi Mudduluru 23*faabdfcfSRashmi Mudduluru namespace { 24*faabdfcfSRashmi Mudduluru 25*faabdfcfSRashmi Mudduluru class TrustReturnsNonnullChecker : public Checker<check::PostCall> { 26*faabdfcfSRashmi Mudduluru 27*faabdfcfSRashmi Mudduluru public: TrustReturnsNonnullChecker(ASTContext & Ctx)28*faabdfcfSRashmi Mudduluru TrustReturnsNonnullChecker(ASTContext &Ctx) {} 29*faabdfcfSRashmi Mudduluru checkPostCall(const CallEvent & Call,CheckerContext & C) const30*faabdfcfSRashmi Mudduluru void checkPostCall(const CallEvent &Call, CheckerContext &C) const { 31*faabdfcfSRashmi Mudduluru ProgramStateRef State = C.getState(); 32*faabdfcfSRashmi Mudduluru 33*faabdfcfSRashmi Mudduluru if (isNonNullPtr(Call)) 34*faabdfcfSRashmi Mudduluru if (auto L = Call.getReturnValue().getAs<Loc>()) 35*faabdfcfSRashmi Mudduluru State = State->assume(*L, /*assumption=*/true); 36*faabdfcfSRashmi Mudduluru 37*faabdfcfSRashmi Mudduluru C.addTransition(State); 38*faabdfcfSRashmi Mudduluru } 39*faabdfcfSRashmi Mudduluru 40*faabdfcfSRashmi Mudduluru private: 41*faabdfcfSRashmi Mudduluru /// \returns Whether the method declaration has the attribute returns_nonnull. isNonNullPtr(const CallEvent & Call) const42*faabdfcfSRashmi Mudduluru bool isNonNullPtr(const CallEvent &Call) const { 43*faabdfcfSRashmi Mudduluru QualType ExprRetType = Call.getResultType(); 44*faabdfcfSRashmi Mudduluru const Decl *CallDeclaration = Call.getDecl(); 45*faabdfcfSRashmi Mudduluru if (!ExprRetType->isAnyPointerType() || !CallDeclaration) 46*faabdfcfSRashmi Mudduluru return false; 47*faabdfcfSRashmi Mudduluru 48*faabdfcfSRashmi Mudduluru return CallDeclaration->hasAttr<ReturnsNonNullAttr>(); 49*faabdfcfSRashmi Mudduluru } 50*faabdfcfSRashmi Mudduluru }; 51*faabdfcfSRashmi Mudduluru 52*faabdfcfSRashmi Mudduluru } // namespace 53*faabdfcfSRashmi Mudduluru registerTrustReturnsNonnullChecker(CheckerManager & Mgr)54*faabdfcfSRashmi Mudduluruvoid ento::registerTrustReturnsNonnullChecker(CheckerManager &Mgr) { 55*faabdfcfSRashmi Mudduluru Mgr.registerChecker<TrustReturnsNonnullChecker>(Mgr.getASTContext()); 56*faabdfcfSRashmi Mudduluru } 57*faabdfcfSRashmi Mudduluru shouldRegisterTrustReturnsNonnullChecker(const CheckerManager & mgr)58*faabdfcfSRashmi Muddulurubool ento::shouldRegisterTrustReturnsNonnullChecker(const CheckerManager &mgr) { 59*faabdfcfSRashmi Mudduluru return true; 60*faabdfcfSRashmi Mudduluru } 61