Coverage Report

Created: 2021-03-06 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- AnalyzerOptions.cpp - Analysis Engine Options ----------------------===//
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
// This file contains special accessors for analyzer configuration options
10
// with string representations.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
15
#include "clang/StaticAnalyzer/Core/Checker.h"
16
#include "llvm/ADT/SmallString.h"
17
#include "llvm/ADT/StringSwitch.h"
18
#include "llvm/ADT/StringRef.h"
19
#include "llvm/ADT/Twine.h"
20
#include "llvm/Support/ErrorHandling.h"
21
#include "llvm/Support/FileSystem.h"
22
#include "llvm/Support/FormattedStream.h"
23
#include "llvm/Support/raw_ostream.h"
24
#include <cassert>
25
#include <cstddef>
26
#include <utility>
27
#include <vector>
28
29
using namespace clang;
30
using namespace ento;
31
using namespace llvm;
32
33
void AnalyzerOptions::printFormattedEntry(
34
    llvm::raw_ostream &Out,
35
    std::pair<StringRef, StringRef> EntryDescPair,
36
1.21k
    size_t InitialPad, size_t EntryWidth, size_t MinLineWidth) {
37
38
1.21k
  llvm::formatted_raw_ostream FOut(Out);
39
40
1.21k
  const size_t PadForDesc = InitialPad + EntryWidth;
41
42
1.21k
  FOut.PadToColumn(InitialPad) << EntryDescPair.first;
43
  // If the buffer's length is greater than PadForDesc, print a newline.
44
1.21k
  if (FOut.getColumn() > PadForDesc)
45
275
    FOut << '\n';
46
47
1.21k
  FOut.PadToColumn(PadForDesc);
48
49
1.21k
  if (MinLineWidth == 0) {
50
920
    FOut << EntryDescPair.second;
51
920
    return;
52
920
  }
53
54
35.3k
  
for (char C : EntryDescPair.second)291
{
55
35.3k
    if (FOut.getColumn() > MinLineWidth && 
C == ' '3.32k
) {
56
649
      FOut << '\n';
57
649
      FOut.PadToColumn(PadForDesc);
58
649
      continue;
59
649
    }
60
34.6k
    FOut << C;
61
34.6k
  }
62
291
}
63
64
ExplorationStrategyKind
65
13.8k
AnalyzerOptions::getExplorationStrategy() const {
66
13.8k
  auto K =
67
13.8k
    llvm::StringSwitch<llvm::Optional<ExplorationStrategyKind>>(
68
13.8k
                                                            ExplorationStrategy)
69
13.8k
          .Case("dfs", ExplorationStrategyKind::DFS)
70
13.8k
          .Case("bfs", ExplorationStrategyKind::BFS)
71
13.8k
          .Case("unexplored_first",
72
13.8k
                ExplorationStrategyKind::UnexploredFirst)
73
13.8k
          .Case("unexplored_first_queue",
74
13.8k
                ExplorationStrategyKind::UnexploredFirstQueue)
75
13.8k
          .Case("unexplored_first_location_queue",
76
13.8k
                ExplorationStrategyKind::UnexploredFirstLocationQueue)
77
13.8k
          .Case("bfs_block_dfs_contents",
78
13.8k
                ExplorationStrategyKind::BFSBlockDFSContents)
79
13.8k
          .Default(None);
80
13.8k
  assert(K.hasValue() && "User mode is invalid.");
81
0
  return K.getValue();
82
13.8k
}
83
84
154k
IPAKind AnalyzerOptions::getIPAMode() const {
85
154k
  auto K = llvm::StringSwitch<llvm::Optional<IPAKind>>(IPAMode)
86
154k
          .Case("none", IPAK_None)
87
154k
          .Case("basic-inlining", IPAK_BasicInlining)
88
154k
          .Case("inlining", IPAK_Inlining)
89
154k
          .Case("dynamic", IPAK_DynamicDispatch)
90
154k
          .Case("dynamic-bifurcate", IPAK_DynamicDispatchBifurcate)
91
154k
          .Default(None);
92
154k
  assert(K.hasValue() && "IPA Mode is invalid.");
93
94
0
  return K.getValue();
95
154k
}
96
97
bool
98
AnalyzerOptions::mayInlineCXXMemberFunction(
99
17.3k
                                          CXXInlineableMemberKind Param) const {
100
17.3k
  if (getIPAMode() < IPAK_Inlining)
101
0
    return false;
102
103
17.3k
  auto K =
104
17.3k
    llvm::StringSwitch<llvm::Optional<CXXInlineableMemberKind>>(
105
17.3k
                                                          CXXMemberInliningMode)
106
17.3k
    .Case("constructors", CIMK_Constructors)
107
17.3k
    .Case("destructors", CIMK_Destructors)
108
17.3k
    .Case("methods", CIMK_MemberFunctions)
109
17.3k
    .Case("none", CIMK_None)
110
17.3k
    .Default(None);
111
112
17.3k
  assert(K.hasValue() && "Invalid c++ member function inlining mode.");
113
114
0
  return *K >= Param;
115
17.3k
}
116
117
StringRef AnalyzerOptions::getCheckerStringOption(StringRef CheckerName,
118
                                                  StringRef OptionName,
119
10.7k
                                                  bool SearchInParents) const {
120
10.7k
  assert(!CheckerName.empty() &&
121
10.7k
         "Empty checker name! Make sure the checker object (including it's "
122
10.7k
         "bases!) if fully initialized before calling this function!");
123
124
0
  ConfigTable::const_iterator E = Config.end();
125
10.9k
  do {
126
10.9k
    ConfigTable::const_iterator I =
127
10.9k
        Config.find((Twine(CheckerName) + ":" + OptionName).str());
128
10.9k
    if (I != E)
129
10.7k
      return StringRef(I->getValue());
130
127
    size_t Pos = CheckerName.rfind('.');
131
127
    if (Pos == StringRef::npos)
132
0
      break;
133
134
127
    CheckerName = CheckerName.substr(0, Pos);
135
127
  } while (!CheckerName.empty() && SearchInParents);
136
137
10.7k
  
llvm_unreachable0
("Unknown checker option! Did you call getChecker*Option "
138
10.7k
                   "with incorrect parameters? User input must've been "
139
10.7k
                   "verified by CheckerRegistry.");
140
141
0
  return "";
142
10.7k
}
143
144
StringRef AnalyzerOptions::getCheckerStringOption(const ento::CheckerBase *C,
145
                                                  StringRef OptionName,
146
130
                                                  bool SearchInParents) const {
147
130
  return getCheckerStringOption(
148
130
                           C->getTagDescription(), OptionName, SearchInParents);
149
130
}
150
151
bool AnalyzerOptions::getCheckerBooleanOption(StringRef CheckerName,
152
                                              StringRef OptionName,
153
10.6k
                                              bool SearchInParents) const {
154
10.6k
  auto Ret = llvm::StringSwitch<llvm::Optional<bool>>(
155
10.6k
      getCheckerStringOption(CheckerName, OptionName,
156
10.6k
                             SearchInParents))
157
10.6k
      .Case("true", true)
158
10.6k
      .Case("false", false)
159
10.6k
      .Default(None);
160
161
10.6k
  assert(Ret &&
162
10.6k
         "This option should be either 'true' or 'false', and should've been "
163
10.6k
         "validated by CheckerRegistry!");
164
165
0
  return *Ret;
166
10.6k
}
167
168
bool AnalyzerOptions::getCheckerBooleanOption(const ento::CheckerBase *C,
169
                                              StringRef OptionName,
170
1.89k
                                              bool SearchInParents) const {
171
1.89k
  return getCheckerBooleanOption(
172
1.89k
             C->getTagDescription(), OptionName, SearchInParents);
173
1.89k
}
174
175
int AnalyzerOptions::getCheckerIntegerOption(StringRef CheckerName,
176
                                             StringRef OptionName,
177
38
                                             bool SearchInParents) const {
178
38
  int Ret = 0;
179
38
  bool HasFailed = getCheckerStringOption(CheckerName, OptionName,
180
38
                                          SearchInParents)
181
38
                     .getAsInteger(0, Ret);
182
38
  assert(!HasFailed &&
183
38
         "This option should be numeric, and should've been validated by "
184
38
         "CheckerRegistry!");
185
0
  (void)HasFailed;
186
38
  return Ret;
187
38
}
188
189
int AnalyzerOptions::getCheckerIntegerOption(const ento::CheckerBase *C,
190
                                             StringRef OptionName,
191
38
                                             bool SearchInParents) const {
192
38
  return getCheckerIntegerOption(
193
38
                           C->getTagDescription(), OptionName, SearchInParents);
194
38
}