Skip to content

Commit

Permalink
Merged master:e9f943429c8 into amd-gfx:f8416c3e42a
Browse files Browse the repository at this point in the history
Local branch amd-gfx f8416c3 Merged master:edc7da24057 into amd-gfx:5925a948df2
Remote branch master e9f9434 [lldb] Skip TestIOHandlerResizeNoEditline on Windows
  • Loading branch information
Sw authored and Sw committed Jul 8, 2020
2 parents f8416c3 + e9f9434 commit 9ba3de3
Show file tree
Hide file tree
Showing 51 changed files with 1,364 additions and 374 deletions.
13 changes: 13 additions & 0 deletions clang/docs/analyzer/checkers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1836,6 +1836,19 @@ Check unreachable code.
[x retain]; // warn
}
.. _alpha-cplusplus-SmartPtr:
alpha.cplusplus.SmartPtr (C++)
""""""""""""""""""""""""""""""
Check for dereference of null smart pointers.
.. code-block:: cpp
void deref_smart_ptr() {
std::unique_ptr<int> P;
*P; // warn: dereference of a default constructed smart unique_ptr
}
alpha.llvm
^^^^^^^^^^
Expand Down
15 changes: 14 additions & 1 deletion clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
Original file line number Diff line number Diff line change
Expand Up @@ -577,9 +577,17 @@ def CXXSelfAssignmentChecker : Checker<"SelfAssignment">,
Documentation<NotDocumented>,
Hidden;

def SmartPtrModeling: Checker<"SmartPtr">,
def SmartPtrModeling: Checker<"SmartPtrModeling">,
HelpText<"Model behavior of C++ smart pointers">,
Documentation<NotDocumented>,
CheckerOptions<[
CmdLineOption<Boolean,
"ModelSmartPtrDereference",
"Enable modeling for SmartPtr null dereferences",
"false",
InAlpha,
Hide>,
]>,
Hidden;

def MoveChecker: Checker<"Move">,
Expand Down Expand Up @@ -736,6 +744,11 @@ def MismatchedIteratorChecker : Checker<"MismatchedIterator">,
Dependencies<[IteratorModeling]>,
Documentation<HasAlphaDocumentation>;

def SmartPtrChecker: Checker<"SmartPtr">,
HelpText<"Find the dereference of null SmrtPtr">,
Dependencies<[SmartPtrModeling]>,
Documentation<HasAlphaDocumentation>;

} // end: "alpha.cplusplus"


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,10 @@ class CXXMemberOperatorCall : public CXXInstanceCall {
// to implicit this-parameter on the declaration.
return CallArgumentIndex + 1;
}

OverloadedOperatorKind getOverloadedOperator() const {
return getOriginExpr()->getOperator();
}
};

/// Represents an implicit call to a C++ destructor.
Expand Down
1 change: 1 addition & 0 deletions clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ add_clang_library(clangStaticAnalyzerCheckers
ReturnValueChecker.cpp
RunLoopAutoreleaseLeakChecker.cpp
SimpleStreamChecker.cpp
SmartPtrChecker.cpp
SmartPtrModeling.cpp
StackAddrEscapeChecker.cpp
StdLibraryFunctionsChecker.cpp
Expand Down
40 changes: 40 additions & 0 deletions clang/lib/StaticAnalyzer/Checkers/SmartPtr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//=== SmartPtr.h - Tracking smart pointer state. -------------------*- 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
//
//===----------------------------------------------------------------------===//
//
// Defines inter-checker API for the smart pointer modeling. It allows
// dependent checkers to figure out if an smart pointer is null or not.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SMARTPTR_H
#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SMARTPTR_H

#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"

namespace clang {
namespace ento {
namespace smartptr {

/// Set of STL smart pointer class which we are trying to model.
const llvm::StringSet<> StdSmartPtrs = {
"shared_ptr",
"unique_ptr",
"weak_ptr",
};

/// Returns true if the event call is on smart pointer.
bool isStdSmartPtrCall(const CallEvent &Call);

/// Returns whether the smart pointer is null or not.
bool isNullSmartPtr(const ProgramStateRef State, const MemRegion *ThisRegion);

} // namespace smartptr
} // namespace ento
} // namespace clang

#endif // LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SMARTPTR_H
80 changes: 80 additions & 0 deletions clang/lib/StaticAnalyzer/Checkers/SmartPtrChecker.cpp
Original file line number Diff line number Diff line change
@@ -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<check::PreCall> {
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<CXXMemberOperatorCall>(&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<PathSensitiveBugReport>(
NullDereferenceBugType, "Dereference of null smart pointer", ErrNode);
C.emitReport(std::move(R));
}

void ento::registerSmartPtrChecker(CheckerManager &Mgr) {
Mgr.registerChecker<SmartPtrChecker>();
}

bool ento::shouldRegisterSmartPtrChecker(const CheckerManager &mgr) {
const LangOptions &LO = mgr.getLangOpts();
return LO.CPlusPlus;
}
Loading

0 comments on commit 9ba3de3

Please sign in to comment.