1//=======- ASTUtis.h ---------------------------------------------*- C++ -*-==//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_ANALYZER_WEBKIT_ASTUTILS_H
10#define LLVM_CLANG_ANALYZER_WEBKIT_ASTUTILS_H
11
12#include "clang/AST/Decl.h"
13#include "llvm/ADT/APInt.h"
14#include "llvm/Support/Casting.h"
15
16#include <string>
17#include <utility>
18
19namespace clang {
20class Expr;
21
22/// This function de-facto defines a set of transformations that we consider
23/// safe (in heuristical sense). These transformation if passed a safe value as
24/// an input should provide a safe value (or an object that provides safe
25/// values).
26///
27/// For more context see Static Analyzer checkers documentation - specifically
28/// webkit.UncountedCallArgsChecker checker. Allowed list of transformations:
29/// - constructors of ref-counted types (including factory methods)
30/// - getters of ref-counted types
31/// - member overloaded operators
32/// - casts
33/// - unary operators like ``&`` or ``*``
34///
35/// If passed expression is of type uncounted pointer/reference we try to find
36/// the "origin" of the pointer value.
37/// Origin can be for example a local variable, nullptr, constant or
38/// this-pointer.
39///
40/// Certain subexpression nodes represent transformations that don't affect
41/// where the memory address originates from. We try to traverse such
42/// subexpressions to get to the relevant child nodes. Whenever we encounter a
43/// subexpression that either can't be ignored, we don't model its semantics or
44/// that has multiple children we stop.
45///
46/// \p E is an expression of uncounted pointer/reference type.
47/// If \p StopAtFirstRefCountedObj is true and we encounter a subexpression that
48/// represents ref-counted object during the traversal we return relevant
49/// sub-expression and true.
50///
51/// \returns subexpression that we traversed to and if \p
52/// StopAtFirstRefCountedObj is true we also return whether we stopped early.
53std::pair<const clang::Expr *, bool>
54tryToFindPtrOrigin(const clang::Expr *E, bool StopAtFirstRefCountedObj);
55
56/// For \p E referring to a ref-countable/-counted pointer/reference we return
57/// whether it's a safe call argument. Examples: function parameter or
58/// this-pointer. The logic relies on the set of recursive rules we enforce for
59/// WebKit codebase.
60///
61/// \returns Whether \p E is a safe call arugment.
62bool isASafeCallArg(const clang::Expr *E);
63
64/// \returns name of AST node or empty string.
65template <typename T> std::string safeGetName(const T *ASTNode) {
66 const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode);
67 if (!ND)
68 return "";
69
70 // In case F is for example "operator|" the getName() method below would
71 // assert.
72 if (!ND->getDeclName().isIdentifier())
73 return "";
74
75 return ND->getName().str();
76}
77
78} // namespace clang
79
80#endif
81

source code of clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h