1 //===-- ChromiumCheckModel.cpp ----------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "clang/Analysis/FlowSensitive/Models/ChromiumCheckModel.h"
10 #include "clang/AST/Decl.h"
11 #include "clang/AST/DeclCXX.h"
12 #include "llvm/ADT/DenseSet.h"
17 /// Determines whether `D` is one of the methods used to implement Chromium's
18 /// `CHECK` macros. Populates `CheckDecls`, if empty.
19 bool isCheckLikeMethod(llvm::SmallDenseSet
<const CXXMethodDecl
*> &CheckDecls
,
20 const CXXMethodDecl
&D
) {
21 // All of the methods of interest are static, so avoid any lookup for
22 // non-static methods (the common case).
26 if (CheckDecls
.empty()) {
27 // Attempt to initialize `CheckDecls` with the methods in class
29 const CXXRecordDecl
*ParentClass
= D
.getParent();
30 if (ParentClass
== nullptr || !ParentClass
->getDeclName().isIdentifier() ||
31 ParentClass
->getName() != "CheckError")
34 // Check whether namespace is "logging".
36 dyn_cast_or_null
<NamespaceDecl
>(ParentClass
->getDeclContext());
37 if (N
== nullptr || !N
->getDeclName().isIdentifier() ||
38 N
->getName() != "logging")
41 // Check whether "logging" is a top-level namespace.
42 if (N
->getParent() == nullptr || !N
->getParent()->isTranslationUnit())
45 for (const CXXMethodDecl
*M
: ParentClass
->methods())
46 if (M
->getDeclName().isIdentifier() && M
->getName().endswith("Check"))
50 return CheckDecls
.contains(&D
);
53 bool ChromiumCheckModel::transfer(const CFGElement
&Element
, Environment
&Env
) {
54 auto CS
= Element
.getAs
<CFGStmt
>();
57 auto Stmt
= CS
->getStmt();
58 if (const auto *Call
= dyn_cast
<CallExpr
>(Stmt
)) {
59 if (const auto *M
= dyn_cast
<CXXMethodDecl
>(Call
->getDirectCallee())) {
60 if (isCheckLikeMethod(CheckDecls
, *M
)) {
61 // Mark this branch as unreachable.
62 Env
.assume(Env
.arena().makeLiteral(false));
70 } // namespace dataflow