Coverage Report

Created: 2022-07-16 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h
Line
Count
Source (jump to first uncovered line)
1
//===- CallDescription.h - function/method call matching       --*- 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
/// \file This file defines a generic mechanism for matching for function and
10
/// method calls of C, C++, and Objective-C languages. Instances of these
11
/// classes are frequently used together with the CallEvent classes.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLDESCRIPTION_H
16
#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLDESCRIPTION_H
17
18
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
19
#include "llvm/ADT/ArrayRef.h"
20
#include "llvm/ADT/Optional.h"
21
#include "llvm/Support/Compiler.h"
22
#include <vector>
23
24
namespace clang {
25
class IdentifierInfo;
26
} // namespace clang
27
28
namespace clang {
29
namespace ento {
30
31
enum CallDescriptionFlags : unsigned {
32
  CDF_None = 0,
33
34
  /// Describes a C standard function that is sometimes implemented as a macro
35
  /// that expands to a compiler builtin with some __builtin prefix.
36
  /// The builtin may as well have a few extra arguments on top of the requested
37
  /// number of arguments.
38
  CDF_MaybeBuiltin = 1 << 0,
39
};
40
41
/// This class represents a description of a function call using the number of
42
/// arguments and the name of the function.
43
class CallDescription {
44
  friend class CallEvent;
45
  using MaybeCount = Optional<unsigned>;
46
47
  mutable Optional<const IdentifierInfo *> II;
48
  // The list of the qualified names used to identify the specified CallEvent,
49
  // e.g. "{a, b}" represent the qualified names, like "a::b".
50
  std::vector<std::string> QualifiedName;
51
  MaybeCount RequiredArgs;
52
  MaybeCount RequiredParams;
53
  int Flags;
54
55
public:
56
  /// Constructs a CallDescription object.
57
  ///
58
  /// @param QualifiedName The list of the name qualifiers of the function that
59
  /// will be matched. The user is allowed to skip any of the qualifiers.
60
  /// For example, {"std", "basic_string", "c_str"} would match both
61
  /// std::basic_string<...>::c_str() and std::__1::basic_string<...>::c_str().
62
  ///
63
  /// @param RequiredArgs The number of arguments that is expected to match a
64
  /// call. Omit this parameter to match every occurrence of call with a given
65
  /// name regardless the number of arguments.
66
  CallDescription(CallDescriptionFlags Flags,
67
                  ArrayRef<const char *> QualifiedName,
68
                  MaybeCount RequiredArgs = None,
69
                  MaybeCount RequiredParams = None);
70
71
  /// Construct a CallDescription with default flags.
72
  CallDescription(ArrayRef<const char *> QualifiedName,
73
                  MaybeCount RequiredArgs = None,
74
                  MaybeCount RequiredParams = None);
75
76
  CallDescription(std::nullptr_t) = delete;
77
78
  /// Get the name of the function that this object matches.
79
774k
  StringRef getFunctionName() const { return QualifiedName.back(); }
80
81
  /// Get the qualified name parts in reversed order.
82
  /// E.g. { "std", "vector", "data" } -> "vector", "std"
83
2.74k
  auto begin_qualified_name_parts() const {
84
2.74k
    return std::next(QualifiedName.rbegin());
85
2.74k
  }
86
2.74k
  auto end_qualified_name_parts() const { return QualifiedName.rend(); }
87
88
  /// It's false, if and only if we expect a single identifier, such as
89
  /// `getenv`. It's true for `std::swap`, or `my::detail::container::data`.
90
12.8k
  bool hasQualifiedNameParts() const { return QualifiedName.size() > 1; }
91
92
  /// @name Matching CallDescriptions against a CallEvent
93
  /// @{
94
95
  /// Returns true if the CallEvent is a call to a function that matches
96
  /// the CallDescription.
97
  ///
98
  /// \note This function is not intended to be used to match Obj-C method
99
  /// calls.
100
  bool matches(const CallEvent &Call) const;
101
102
  /// Returns true whether the CallEvent matches on any of the CallDescriptions
103
  /// supplied.
104
  ///
105
  /// \note This function is not intended to be used to match Obj-C method
106
  /// calls.
107
75.9k
  friend bool matchesAny(const CallEvent &Call, const CallDescription &CD1) {
108
75.9k
    return CD1.matches(Call);
109
75.9k
  }
110
111
  /// \copydoc clang::ento::CallDescription::matchesAny(const CallEvent &, const CallDescription &)
112
  template <typename... Ts>
113
  friend bool matchesAny(const CallEvent &Call, const CallDescription &CD1,
114
144k
                         const Ts &...CDs) {
115
144k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)144k
;
116
144k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
75.9k
                         const Ts &...CDs) {
115
75.9k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)75.9k
;
116
75.9k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
3.59k
                         const Ts &...CDs) {
115
3.59k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)3.59k
;
116
3.59k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
3.59k
                         const Ts &...CDs) {
115
3.59k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)3.59k
;
116
3.59k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
3.59k
                         const Ts &...CDs) {
115
3.59k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)3.59k
;
116
3.59k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
3.59k
                         const Ts &...CDs) {
115
3.59k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)3.59k
;
116
3.59k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
3.59k
                         const Ts &...CDs) {
115
3.59k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)3.59k
;
116
3.59k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
3.59k
                         const Ts &...CDs) {
115
3.59k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)3.59k
;
116
3.59k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
3.71k
                         const Ts &...CDs) {
115
3.71k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)3.69k
;
116
3.71k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
3.80k
                         const Ts &...CDs) {
115
3.80k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)3.78k
;
116
3.80k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription, clang::ento::CallDescription, clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
3.78k
                         const Ts &...CDs) {
115
3.78k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)3.77k
;
116
3.78k
  }
bool clang::ento::matchesAny<clang::ento::CallDescription, clang::ento::CallDescription>(clang::ento::CallEvent const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&, clang::ento::CallDescription const&)
Line
Count
Source
114
36.0k
                         const Ts &...CDs) {
115
36.0k
    return CD1.matches(Call) || 
matchesAny(Call, CDs...)35.9k
;
116
36.0k
  }
117
  /// @}
118
119
  /// @name Matching CallDescriptions against a CallExpr
120
  /// @{
121
122
  /// Returns true if the CallExpr is a call to a function that matches the
123
  /// CallDescription.
124
  ///
125
  /// When available, always prefer matching with a CallEvent! This function
126
  /// exists only when that is not available, for example, when _only_
127
  /// syntactic check is done on a piece of code.
128
  ///
129
  /// Also, StdLibraryFunctionsChecker::Signature is likely a better candicade
130
  /// for syntactic only matching if you are writing a new checker. This is
131
  /// handy if a CallDescriptionMap is already there.
132
  ///
133
  /// The function is imprecise because CallEvent may know path sensitive
134
  /// information, such as the precise argument count (see comments for
135
  /// CallEvent::getNumArgs), the called function if it was called through a
136
  /// function pointer, and other information not available syntactically.
137
  bool matchesAsWritten(const CallExpr &CE) const;
138
139
  /// Returns true whether the CallExpr matches on any of the CallDescriptions
140
  /// supplied.
141
  ///
142
  /// \note This function is not intended to be used to match Obj-C method
143
  /// calls.
144
  friend bool matchesAnyAsWritten(const CallExpr &CE,
145
0
                                  const CallDescription &CD1) {
146
0
    return CD1.matchesAsWritten(CE);
147
0
  }
148
149
  /// \copydoc clang::ento::CallDescription::matchesAnyAsWritten(const CallExpr &, const CallDescription &)
150
  template <typename... Ts>
151
  friend bool matchesAnyAsWritten(const CallExpr &CE,
152
                                  const CallDescription &CD1,
153
                                  const Ts &...CDs) {
154
    return CD1.matchesAsWritten(CE) || matchesAnyAsWritten(CE, CDs...);
155
  }
156
  /// @}
157
158
private:
159
  bool matchesImpl(const FunctionDecl *Callee, size_t ArgCount,
160
                   size_t ParamCount) const;
161
};
162
163
/// An immutable map from CallDescriptions to arbitrary data. Provides a unified
164
/// way for checkers to react on function calls.
165
template <typename T> class CallDescriptionMap {
166
  friend class CallDescriptionSet;
167
168
  // Some call descriptions aren't easily hashable (eg., the ones with qualified
169
  // names in which some sections are omitted), so let's put them
170
  // in a simple vector and use linear lookup.
171
  // TODO: Implement an actual map for fast lookup for "hashable" call
172
  // descriptions (eg., the ones for C functions that just match the name).
173
  std::vector<std::pair<CallDescription, T>> LinearMap;
174
175
public:
176
  CallDescriptionMap(
177
      std::initializer_list<std::pair<CallDescription, T>> &&List)
178
1.70k
      : LinearMap(List) {}
CStringChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::CStringChecker::*)(clang::ento::CheckerContext&, clang::CallExpr const*) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::CStringChecker::*)(clang::ento::CheckerContext&, clang::CallExpr const*) const> >&&)
Line
Count
Source
178
264
      : LinearMap(List) {}
CastValueChecker.cpp:clang::ento::CallDescriptionMap<std::__1::pair<std::__1::function<void ((anonymous namespace)::CastValueChecker const*, clang::ento::CallEvent const&, clang::ento::DefinedOrUnknownSVal, clang::ento::CheckerContext&)>, (anonymous namespace)::CastValueChecker::CallKind> >::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, std::__1::pair<std::__1::function<void ((anonymous namespace)::CastValueChecker const*, clang::ento::CallEvent const&, clang::ento::DefinedOrUnknownSVal, clang::ento::CheckerContext&)>, (anonymous namespace)::CastValueChecker::CallKind> > >&&)
Line
Count
Source
178
53
      : LinearMap(List) {}
ContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::Expr const*) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::Expr const*) const> >&&)
Line
Count
Source
178
21
      : LinearMap(List) {}
ContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal) const> >&&)
Line
Count
Source
178
21
      : LinearMap(List) {}
ContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal, clang::ento::SVal) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal, clang::ento::SVal) const> >&&)
Line
Count
Source
178
21
      : LinearMap(List) {}
DebugContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::DebugContainerModeling::*)(clang::CallExpr const*, clang::ento::CheckerContext&) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::DebugContainerModeling::*)(clang::CallExpr const*, clang::ento::CheckerContext&) const> >&&)
Line
Count
Source
178
13
      : LinearMap(List) {}
DebugIteratorModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::DebugIteratorModeling::*)(clang::CallExpr const*, clang::ento::CheckerContext&) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::DebugIteratorModeling::*)(clang::CallExpr const*, clang::ento::CheckerContext&) const> >&&)
Line
Count
Source
178
11
      : LinearMap(List) {}
clang::ento::CallDescriptionMap<std::__1::function<void (clang::ento::CheckerContext&, clang::ento::CallEvent const&)> >::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, std::__1::function<void (clang::ento::CheckerContext&, clang::ento::CallEvent const&)> > >&&)
Line
Count
Source
178
6
      : LinearMap(List) {}
GenericTaintChecker.cpp:clang::ento::CallDescriptionMap<(anonymous namespace)::GenericTaintRule>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, (anonymous namespace)::GenericTaintRule> >&&)
Line
Count
Source
178
22
      : LinearMap(List) {}
InvalidPtrChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::InvalidPtrChecker::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::InvalidPtrChecker::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&) const> >&&)
Line
Count
Source
178
14
      : LinearMap(List) {}
IteratorModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::IteratorModeling::*)(clang::ento::CheckerContext&, clang::Expr const*, clang::ento::SVal, clang::ento::SVal, clang::ento::SVal) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::IteratorModeling::*)(clang::ento::CheckerContext&, clang::Expr const*, clang::ento::SVal, clang::ento::SVal, clang::ento::SVal) const> >&&)
Line
Count
Source
178
19
      : LinearMap(List) {}
IteratorRangeChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::IteratorRangeChecker::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::IteratorRangeChecker::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal) const> >&&)
Line
Count
Source
178
2
      : LinearMap(List) {}
MallocChecker.cpp:clang::ento::CallDescriptionMap<std::__1::function<void ((anonymous namespace)::MallocChecker const*, clang::ento::CallEvent const&, clang::ento::CheckerContext&)> >::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, std::__1::function<void ((anonymous namespace)::MallocChecker const*, clang::ento::CallEvent const&, clang::ento::CheckerContext&)> > >&&)
Line
Count
Source
178
723
      : LinearMap(List) {}
PthreadLockChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::PthreadLockChecker::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&, (anonymous namespace)::PthreadLockChecker::CheckerKind) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::PthreadLockChecker::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&, (anonymous namespace)::PthreadLockChecker::CheckerKind) const> >&&)
Line
Count
Source
178
231
      : LinearMap(List) {}
clang::ento::CallDescriptionMap<bool>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, bool> >&&)
Line
Count
Source
178
181
      : LinearMap(List) {}
SmartPtrModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::SmartPtrModeling::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, void ((anonymous namespace)::SmartPtrModeling::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&) const> >&&)
Line
Count
Source
178
77
      : LinearMap(List) {}
STLAlgorithmModeling.cpp:clang::ento::CallDescriptionMap<bool ((anonymous namespace)::STLAlgorithmModeling::*)(clang::ento::CheckerContext&, clang::CallExpr const*) const>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, bool ((anonymous namespace)::STLAlgorithmModeling::*)(clang::ento::CheckerContext&, clang::CallExpr const*) const> >&&)
Line
Count
Source
178
2
      : LinearMap(List) {}
StreamChecker.cpp:clang::ento::CallDescriptionMap<(anonymous namespace)::FnDescription>::CallDescriptionMap(std::initializer_list<std::__1::pair<clang::ento::CallDescription, (anonymous namespace)::FnDescription> >&&)
Line
Count
Source
178
22
      : LinearMap(List) {}
179
180
  template <typename InputIt>
181
30
  CallDescriptionMap(InputIt First, InputIt Last) : LinearMap(First, Last) {}
182
183
1.75k
  ~CallDescriptionMap() = default;
CStringChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::CStringChecker::*)(clang::ento::CheckerContext&, clang::CallExpr const*) const>::~CallDescriptionMap()
Line
Count
Source
183
264
  ~CallDescriptionMap() = default;
CastValueChecker.cpp:clang::ento::CallDescriptionMap<std::__1::pair<std::__1::function<void ((anonymous namespace)::CastValueChecker const*, clang::ento::CallEvent const&, clang::ento::DefinedOrUnknownSVal, clang::ento::CheckerContext&)>, (anonymous namespace)::CastValueChecker::CallKind> >::~CallDescriptionMap()
Line
Count
Source
183
53
  ~CallDescriptionMap() = default;
ContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal, clang::ento::SVal) const>::~CallDescriptionMap()
Line
Count
Source
183
21
  ~CallDescriptionMap() = default;
ContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal) const>::~CallDescriptionMap()
Line
Count
Source
183
21
  ~CallDescriptionMap() = default;
ContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::Expr const*) const>::~CallDescriptionMap()
Line
Count
Source
183
21
  ~CallDescriptionMap() = default;
DebugContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::DebugContainerModeling::*)(clang::CallExpr const*, clang::ento::CheckerContext&) const>::~CallDescriptionMap()
Line
Count
Source
183
13
  ~CallDescriptionMap() = default;
DebugIteratorModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::DebugIteratorModeling::*)(clang::CallExpr const*, clang::ento::CheckerContext&) const>::~CallDescriptionMap()
Line
Count
Source
183
11
  ~CallDescriptionMap() = default;
clang::ento::CallDescriptionMap<bool>::~CallDescriptionMap()
Line
Count
Source
183
181
  ~CallDescriptionMap() = default;
clang::ento::CallDescriptionMap<std::__1::function<void (clang::ento::CheckerContext&, clang::ento::CallEvent const&)> >::~CallDescriptionMap()
Line
Count
Source
183
6
  ~CallDescriptionMap() = default;
GenericTaintChecker.cpp:clang::ento::CallDescriptionMap<(anonymous namespace)::GenericTaintRule>::~CallDescriptionMap()
Line
Count
Source
183
74
  ~CallDescriptionMap() = default;
InvalidPtrChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::InvalidPtrChecker::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&) const>::~CallDescriptionMap()
Line
Count
Source
183
14
  ~CallDescriptionMap() = default;
IteratorModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::IteratorModeling::*)(clang::ento::CheckerContext&, clang::Expr const*, clang::ento::SVal, clang::ento::SVal, clang::ento::SVal) const>::~CallDescriptionMap()
Line
Count
Source
183
19
  ~CallDescriptionMap() = default;
IteratorRangeChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::IteratorRangeChecker::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal) const>::~CallDescriptionMap()
Line
Count
Source
183
2
  ~CallDescriptionMap() = default;
MallocChecker.cpp:clang::ento::CallDescriptionMap<std::__1::function<void ((anonymous namespace)::MallocChecker const*, clang::ento::CallEvent const&, clang::ento::CheckerContext&)> >::~CallDescriptionMap()
Line
Count
Source
183
723
  ~CallDescriptionMap() = default;
PthreadLockChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::PthreadLockChecker::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&, (anonymous namespace)::PthreadLockChecker::CheckerKind) const>::~CallDescriptionMap()
Line
Count
Source
183
231
  ~CallDescriptionMap() = default;
SmartPtrModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::SmartPtrModeling::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&) const>::~CallDescriptionMap()
Line
Count
Source
183
77
  ~CallDescriptionMap() = default;
STLAlgorithmModeling.cpp:clang::ento::CallDescriptionMap<bool ((anonymous namespace)::STLAlgorithmModeling::*)(clang::ento::CheckerContext&, clang::CallExpr const*) const>::~CallDescriptionMap()
Line
Count
Source
183
2
  ~CallDescriptionMap() = default;
StreamChecker.cpp:clang::ento::CallDescriptionMap<(anonymous namespace)::FnDescription>::~CallDescriptionMap()
Line
Count
Source
183
22
  ~CallDescriptionMap() = default;
184
185
  // These maps are usually stored once per checker, so let's make sure
186
  // we don't do redundant copies.
187
  CallDescriptionMap(const CallDescriptionMap &) = delete;
188
  CallDescriptionMap &operator=(const CallDescription &) = delete;
189
190
22
  CallDescriptionMap(CallDescriptionMap &&) = default;
191
0
  CallDescriptionMap &operator=(CallDescriptionMap &&) = default;
192
193
193k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
193k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
2.02M
      if (I.first.matches(Call))
198
13.1k
        return &I.second;
199
200
180k
    return nullptr;
201
193k
  }
CStringChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::CStringChecker::*)(clang::ento::CheckerContext&, clang::CallExpr const*) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
19.9k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
19.9k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
453k
      if (I.first.matches(Call))
198
2.08k
        return &I.second;
199
200
17.8k
    return nullptr;
201
19.9k
  }
CastValueChecker.cpp:clang::ento::CallDescriptionMap<std::__1::pair<std::__1::function<void ((anonymous namespace)::CastValueChecker const*, clang::ento::CallEvent const&, clang::ento::DefinedOrUnknownSVal, clang::ento::CheckerContext&)>, (anonymous namespace)::CastValueChecker::CallKind> >::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
590
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
590
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
3.69k
      if (I.first.matches(Call))
198
317
        return &I.second;
199
200
273
    return nullptr;
201
590
  }
ContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::Expr const*) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
3.28k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
3.28k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
25.5k
      if (I.first.matches(Call))
198
187
        return &I.second;
199
200
3.09k
    return nullptr;
201
3.28k
  }
ContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
3.09k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
3.09k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
11.7k
      if (I.first.matches(Call))
198
326
        return &I.second;
199
200
2.76k
    return nullptr;
201
3.09k
  }
ContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::ContainerModeling::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal, clang::ento::SVal) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
2.76k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
2.76k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
5.53k
      if (I.first.matches(Call))
198
8
        return &I.second;
199
200
2.76k
    return nullptr;
201
2.76k
  }
DebugContainerModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::DebugContainerModeling::*)(clang::CallExpr const*, clang::ento::CheckerContext&) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
10.6k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
10.6k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
20.7k
      if (I.first.matches(Call))
198
1.08k
        return &I.second;
199
200
9.52k
    return nullptr;
201
10.6k
  }
DebugIteratorModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::DebugIteratorModeling::*)(clang::CallExpr const*, clang::ento::CheckerContext&) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
10.5k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
10.5k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
28.8k
      if (I.first.matches(Call))
198
2.68k
        return &I.second;
199
200
7.90k
    return nullptr;
201
10.5k
  }
clang::ento::CallDescriptionMap<std::__1::function<void (clang::ento::CheckerContext&, clang::ento::CallEvent const&)> >::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
258
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
258
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
1.18k
      if (I.first.matches(Call))
198
122
        return &I.second;
199
200
136
    return nullptr;
201
258
  }
GenericTaintChecker.cpp:clang::ento::CallDescriptionMap<(anonymous namespace)::GenericTaintRule>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
3.56k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
3.56k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
235k
      if (I.first.matches(Call))
198
1.53k
        return &I.second;
199
200
2.02k
    return nullptr;
201
3.56k
  }
InvalidPtrChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::InvalidPtrChecker::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
194
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
194
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
782
      if (I.first.matches(Call))
198
59
        return &I.second;
199
200
135
    return nullptr;
201
194
  }
IteratorModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::IteratorModeling::*)(clang::ento::CheckerContext&, clang::Expr const*, clang::ento::SVal, clang::ento::SVal, clang::ento::SVal) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
16.0k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
16.0k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
47.9k
      if (I.first.matches(Call))
198
248
        return &I.second;
199
200
15.8k
    return nullptr;
201
16.0k
  }
IteratorRangeChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::IteratorRangeChecker::*)(clang::ento::CheckerContext&, clang::ento::SVal, clang::ento::SVal) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
1.39k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
1.39k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
3.89k
      if (I.first.matches(Call))
198
228
        return &I.second;
199
200
1.17k
    return nullptr;
201
1.39k
  }
MallocChecker.cpp:clang::ento::CallDescriptionMap<std::__1::function<void ((anonymous namespace)::MallocChecker const*, clang::ento::CallEvent const&, clang::ento::CheckerContext&)> >::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
111k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
111k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
1.06M
      if (I.first.matches(Call))
198
2.66k
        return &I.second;
199
200
109k
    return nullptr;
201
111k
  }
PthreadLockChecker.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::PthreadLockChecker::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&, (anonymous namespace)::PthreadLockChecker::CheckerKind) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
5.69k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
5.69k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
71.1k
      if (I.first.matches(Call))
198
521
        return &I.second;
199
200
5.17k
    return nullptr;
201
5.69k
  }
clang::ento::CallDescriptionMap<bool>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
1.89k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
1.89k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
10.0k
      if (I.first.matches(Call))
198
338
        return &I.second;
199
200
1.56k
    return nullptr;
201
1.89k
  }
SmartPtrModeling.cpp:clang::ento::CallDescriptionMap<void ((anonymous namespace)::SmartPtrModeling::*)(clang::ento::CallEvent const&, clang::ento::CheckerContext&) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
155
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
155
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
485
      if (I.first.matches(Call))
198
97
        return &I.second;
199
200
58
    return nullptr;
201
155
  }
STLAlgorithmModeling.cpp:clang::ento::CallDescriptionMap<bool ((anonymous namespace)::STLAlgorithmModeling::*)(clang::ento::CheckerContext&, clang::CallExpr const*) const>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
1.23k
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
1.23k
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
27.9k
      if (I.first.matches(Call))
198
54
        return &I.second;
199
200
1.18k
    return nullptr;
201
1.23k
  }
StreamChecker.cpp:clang::ento::CallDescriptionMap<(anonymous namespace)::FnDescription>::lookup(clang::ento::CallEvent const&) const
Line
Count
Source
193
795
  LLVM_NODISCARD const T *lookup(const CallEvent &Call) const {
194
    // Slow path: linear lookup.
195
    // TODO: Implement some sort of fast path.
196
795
    for (const std::pair<CallDescription, T> &I : LinearMap)
197
6.46k
      if (I.first.matches(Call))
198
576
        return &I.second;
199
200
219
    return nullptr;
201
795
  }
202
203
  /// When available, always prefer lookup with a CallEvent! This function
204
  /// exists only when that is not available, for example, when _only_
205
  /// syntactic check is done on a piece of code.
206
  ///
207
  /// Also, StdLibraryFunctionsChecker::Signature is likely a better candicade
208
  /// for syntactic only matching if you are writing a new checker. This is
209
  /// handy if a CallDescriptionMap is already there.
210
  ///
211
  /// The function is imprecise because CallEvent may know path sensitive
212
  /// information, such as the precise argument count (see comments for
213
  /// CallEvent::getNumArgs), the called function if it was called through a
214
  /// function pointer, and other information not available syntactically.
215
80
  LLVM_NODISCARD const T *lookupAsWritten(const CallExpr &Call) const {
216
    // Slow path: linear lookup.
217
    // TODO: Implement some sort of fast path.
218
80
    for (const std::pair<CallDescription, T> &I : LinearMap)
219
379
      if (I.first.matchesAsWritten(Call))
220
4
        return &I.second;
221
222
76
    return nullptr;
223
80
  }
MallocChecker.cpp:clang::ento::CallDescriptionMap<std::__1::function<void ((anonymous namespace)::MallocChecker const*, clang::ento::CallEvent const&, clang::ento::CheckerContext&)> >::lookupAsWritten(clang::CallExpr const&) const
Line
Count
Source
215
78
  LLVM_NODISCARD const T *lookupAsWritten(const CallExpr &Call) const {
216
    // Slow path: linear lookup.
217
    // TODO: Implement some sort of fast path.
218
78
    for (const std::pair<CallDescription, T> &I : LinearMap)
219
377
      if (I.first.matchesAsWritten(Call))
220
3
        return &I.second;
221
222
75
    return nullptr;
223
78
  }
clang::ento::CallDescriptionMap<bool>::lookupAsWritten(clang::CallExpr const&) const
Line
Count
Source
215
2
  LLVM_NODISCARD const T *lookupAsWritten(const CallExpr &Call) const {
216
    // Slow path: linear lookup.
217
    // TODO: Implement some sort of fast path.
218
2
    for (const std::pair<CallDescription, T> &I : LinearMap)
219
2
      if (I.first.matchesAsWritten(Call))
220
1
        return &I.second;
221
222
1
    return nullptr;
223
2
  }
224
};
225
226
/// An immutable set of CallDescriptions.
227
/// Checkers can efficiently decide if a given CallEvent matches any
228
/// CallDescription in the set.
229
class CallDescriptionSet {
230
  CallDescriptionMap<bool /*unused*/> Impl = {};
231
232
public:
233
  CallDescriptionSet(std::initializer_list<CallDescription> &&List);
234
235
  CallDescriptionSet(const CallDescriptionSet &) = delete;
236
  CallDescriptionSet &operator=(const CallDescription &) = delete;
237
238
  LLVM_NODISCARD bool contains(const CallEvent &Call) const;
239
240
  /// When available, always prefer lookup with a CallEvent! This function
241
  /// exists only when that is not available, for example, when _only_
242
  /// syntactic check is done on a piece of code.
243
  ///
244
  /// Also, StdLibraryFunctionsChecker::Signature is likely a better candicade
245
  /// for syntactic only matching if you are writing a new checker. This is
246
  /// handy if a CallDescriptionMap is already there.
247
  ///
248
  /// The function is imprecise because CallEvent may know path sensitive
249
  /// information, such as the precise argument count (see comments for
250
  /// CallEvent::getNumArgs), the called function if it was called through a
251
  /// function pointer, and other information not available syntactically.
252
  LLVM_NODISCARD bool containsAsWritten(const CallExpr &CE) const;
253
};
254
255
} // namespace ento
256
} // namespace clang
257
258
#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLDESCRIPTION_H