Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h
Line
Count
Source (jump to first uncovered line)
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
19
namespace clang {
20
class 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.
53
std::pair<const clang::Expr *, bool>
54
tryToFindPtrOrigin(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.
62
bool isASafeCallArg(const clang::Expr *E);
63
64
/// \returns name of AST node or empty string.
65
413
template <typename T> std::string safeGetName(const T *ASTNode) {
66
413
  const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode);
67
413
  if (!ND)
68
0
    return "";
69
70
  // In case F is for example "operator|" the getName() method below would
71
  // assert.
72
413
  if (!ND->getDeclName().isIdentifier())
73
26
    return "";
74
75
387
  return ND->getName().str();
76
413
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > clang::safeGetName<clang::CXXMethodDecl>(clang::CXXMethodDecl const*)
Line
Count
Source
65
173
template <typename T> std::string safeGetName(const T *ASTNode) {
66
173
  const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode);
67
173
  if (!ND)
68
0
    return "";
69
70
  // In case F is for example "operator|" the getName() method below would
71
  // assert.
72
173
  if (!ND->getDeclName().isIdentifier())
73
7
    return "";
74
75
166
  return ND->getName().str();
76
173
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > clang::safeGetName<clang::FunctionDecl>(clang::FunctionDecl const*)
Line
Count
Source
65
195
template <typename T> std::string safeGetName(const T *ASTNode) {
66
195
  const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode);
67
195
  if (!ND)
68
0
    return "";
69
70
  // In case F is for example "operator|" the getName() method below would
71
  // assert.
72
195
  if (!ND->getDeclName().isIdentifier())
73
19
    return "";
74
75
176
  return ND->getName().str();
76
195
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > clang::safeGetName<clang::ParmVarDecl>(clang::ParmVarDecl const*)
Line
Count
Source
65
18
template <typename T> std::string safeGetName(const T *ASTNode) {
66
18
  const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode);
67
18
  if (!ND)
68
0
    return "";
69
70
  // In case F is for example "operator|" the getName() method below would
71
  // assert.
72
18
  if (!ND->getDeclName().isIdentifier())
73
0
    return "";
74
75
18
  return ND->getName().str();
76
18
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > clang::safeGetName<clang::CXXRecordDecl>(clang::CXXRecordDecl const*)
Line
Count
Source
65
27
template <typename T> std::string safeGetName(const T *ASTNode) {
66
27
  const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode);
67
27
  if (!ND)
68
0
    return "";
69
70
  // In case F is for example "operator|" the getName() method below would
71
  // assert.
72
27
  if (!ND->getDeclName().isIdentifier())
73
0
    return "";
74
75
27
  return ND->getName().str();
76
27
}
77
78
} // namespace clang
79
80
#endif