From cfca06d7963fa0909f90483b42a6d7d194d01e08 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 26 Jul 2020 19:36:28 +0000 Subject: Vendor import of llvm-project master 2e10b7a39b9, the last commit before the llvmorg-12-init tag, from which release/11.x was branched. --- .../StaticAnalyzer/Checkers/SmartPtrChecker.cpp | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp (limited to 'clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp') diff --git a/clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp new file mode 100644 index 0000000000000..7bb25f397d010 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp @@ -0,0 +1,80 @@ +// SmartPtrChecker.cpp - Check for smart pointer dereference - C++ --------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines a checker that check for null dereference of C++ smart +// pointer. +// +//===----------------------------------------------------------------------===// +#include "SmartPtr.h" + +#include "clang/AST/DeclCXX.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/Type.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" + +using namespace clang; +using namespace ento; + +namespace { +class SmartPtrChecker : public Checker { + BugType NullDereferenceBugType{this, "Null SmartPtr dereference", + "C++ Smart Pointer"}; + +public: + void checkPreCall(const CallEvent &Call, CheckerContext &C) const; + +private: + void reportBug(CheckerContext &C, const CallEvent &Call) const; +}; +} // end of anonymous namespace + +void SmartPtrChecker::checkPreCall(const CallEvent &Call, + CheckerContext &C) const { + if (!smartptr::isStdSmartPtrCall(Call)) + return; + ProgramStateRef State = C.getState(); + const auto *OC = dyn_cast(&Call); + if (!OC) + return; + const MemRegion *ThisRegion = OC->getCXXThisVal().getAsRegion(); + if (!ThisRegion) + return; + + OverloadedOperatorKind OOK = OC->getOverloadedOperator(); + if (OOK == OO_Star || OOK == OO_Arrow) { + if (smartptr::isNullSmartPtr(State, ThisRegion)) + reportBug(C, Call); + } +} + +void SmartPtrChecker::reportBug(CheckerContext &C, + const CallEvent &Call) const { + ExplodedNode *ErrNode = C.generateErrorNode(); + if (!ErrNode) + return; + + auto R = std::make_unique( + NullDereferenceBugType, "Dereference of null smart pointer", ErrNode); + C.emitReport(std::move(R)); +} + +void ento::registerSmartPtrChecker(CheckerManager &Mgr) { + Mgr.registerChecker(); +} + +bool ento::shouldRegisterSmartPtrChecker(const CheckerManager &mgr) { + const LangOptions &LO = mgr.getLangOpts(); + return LO.CPlusPlus; +} -- cgit v1.2.3