diff options
author | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 13:58:24 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.com> | 2024-03-13 14:11:53 +0300 |
commit | 11a895b7e15d1c5a1f52706396b82e3f9db953cb (patch) | |
tree | fabc6d883b0f946151f61ae7865cee9f529a1fdd /contrib/libs/clang16/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp | |
parent | 9685917341315774aad5733b1793b1e533a88bbb (diff) | |
download | ydb-11a895b7e15d1c5a1f52706396b82e3f9db953cb.tar.gz |
Export clang-format16 via ydblib project
6e6be3a95868fde888d801b7590af4044049563f
Diffstat (limited to 'contrib/libs/clang16/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp')
-rw-r--r-- | contrib/libs/clang16/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/contrib/libs/clang16/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp b/contrib/libs/clang16/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp new file mode 100644 index 0000000000..f457964fb1 --- /dev/null +++ b/contrib/libs/clang16/lib/Analysis/FlowSensitive/Models/ChromiumCheckModel.cpp @@ -0,0 +1,71 @@ +//===-- ChromiumCheckModel.cpp ----------------------------------*- 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 +// +//===----------------------------------------------------------------------===// + +#include "clang/Analysis/FlowSensitive/Models/ChromiumCheckModel.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "llvm/ADT/DenseSet.h" + +namespace clang { +namespace dataflow { + +/// Determines whether `D` is one of the methods used to implement Chromium's +/// `CHECK` macros. Populates `CheckDecls`, if empty. +bool isCheckLikeMethod(llvm::SmallDenseSet<const CXXMethodDecl *> &CheckDecls, + const CXXMethodDecl &D) { + // All of the methods of interest are static, so avoid any lookup for + // non-static methods (the common case). + if (!D.isStatic()) + return false; + + if (CheckDecls.empty()) { + // Attempt to initialize `CheckDecls` with the methods in class + // `CheckError`. + const CXXRecordDecl *ParentClass = D.getParent(); + if (ParentClass == nullptr || !ParentClass->getDeclName().isIdentifier() || + ParentClass->getName() != "CheckError") + return false; + + // Check whether namespace is "logging". + const auto *N = + dyn_cast_or_null<NamespaceDecl>(ParentClass->getDeclContext()); + if (N == nullptr || !N->getDeclName().isIdentifier() || + N->getName() != "logging") + return false; + + // Check whether "logging" is a top-level namespace. + if (N->getParent() == nullptr || !N->getParent()->isTranslationUnit()) + return false; + + for (const CXXMethodDecl *M : ParentClass->methods()) + if (M->getDeclName().isIdentifier() && M->getName().endswith("Check")) + CheckDecls.insert(M); + } + + return CheckDecls.contains(&D); +} + +bool ChromiumCheckModel::transfer(const CFGElement *Element, Environment &Env) { + auto CS = Element->getAs<CFGStmt>(); + if (!CS) + return false; + auto Stmt = CS->getStmt(); + if (const auto *Call = dyn_cast<CallExpr>(Stmt)) { + if (const auto *M = dyn_cast<CXXMethodDecl>(Call->getDirectCallee())) { + if (isCheckLikeMethod(CheckDecls, *M)) { + // Mark this branch as unreachable. + Env.addToFlowCondition(Env.getBoolLiteralValue(false)); + return true; + } + } + } + return false; +} + +} // namespace dataflow +} // namespace clang |