Skip to content

Commit fc0c6a0

Browse files
committed
using formatv
1 parent 2ec7140 commit fc0c6a0

File tree

1 file changed

+33
-39
lines changed

1 file changed

+33
-39
lines changed

clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
2222
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
2323
#include "llvm/ADT/StringExtras.h"
24+
#include "llvm/Support/FormatVariadic.h"
2425
#include "llvm/Support/raw_ostream.h"
2526

2627
using namespace clang;
@@ -182,7 +183,8 @@ static void describeUninitializedArgumentInCall(const CallEvent &Call,
182183
namespace {
183184
class FindUninitializedField {
184185
public:
185-
SmallVector<const FieldDecl *, 10> FieldChain;
186+
using FieldChainTy = SmallVector<const FieldDecl *, 10>;
187+
FieldChainTy FieldChain;
186188

187189
private:
188190
StoreManager &StoreMgr;
@@ -219,27 +221,32 @@ class FindUninitializedField {
219221

220222
return false;
221223
}
224+
};
225+
} // namespace
222226

223-
void printFieldChain(llvm::raw_ostream &OS) {
224-
if (FieldChain.size() == 1)
225-
OS << " (e.g., field: '" << *FieldChain[0] << "')";
227+
namespace llvm {
228+
template <> struct format_provider<FindUninitializedField::FieldChainTy> {
229+
static void format(const FindUninitializedField::FieldChainTy &V,
230+
raw_ostream &Stream, StringRef Style) {
231+
if (V.size() == 1)
232+
Stream << "(e.g., field: '" << *V[0] << "')";
226233
else {
227-
OS << " (e.g., via the field chain: '";
234+
Stream << "(e.g., via the field chain: '";
228235
bool First = true;
229-
for (SmallVectorImpl<const FieldDecl *>::iterator DI = FieldChain.begin(),
230-
DE = FieldChain.end();
236+
for (FindUninitializedField::FieldChainTy::const_iterator DI = V.begin(),
237+
DE = V.end();
231238
DI != DE; ++DI) {
232239
if (First)
233240
First = false;
234241
else
235-
OS << '.';
236-
OS << **DI;
242+
Stream << '.';
243+
Stream << **DI;
237244
}
238-
OS << "')";
245+
Stream << "')";
239246
}
240247
}
241248
};
242-
} // namespace
249+
} // namespace llvm
243250

244251
bool CallAndMessageChecker::uninitRefOrPointer(
245252
CheckerContext &C, SVal V, SourceRange ArgRange, const Expr *ArgEx,
@@ -276,15 +283,11 @@ bool CallAndMessageChecker::uninitRefOrPointer(
276283

277284
if (PointeeV.isUndef()) {
278285
if (ExplodedNode *N = C.generateErrorNode()) {
279-
SmallString<200> Buf;
280-
llvm::raw_svector_ostream Os(Buf);
281-
Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
282-
<< " function call argument is ";
283-
if (ParamT->isPointerType())
284-
Os << "a pointer to uninitialized value";
285-
else
286-
Os << "an uninitialized value";
287-
auto R = std::make_unique<PathSensitiveBugReport>(BT, Os.str(), N);
286+
std::string Msg = llvm::formatv(
287+
"{0}{1} function call argument is {2} uninitialized value",
288+
ArgumentNumber + 1, llvm::getOrdinalSuffix(ArgumentNumber + 1),
289+
ParamT->isPointerType() ? "a pointer to" : "an");
290+
auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
288291
R->addRange(ArgRange);
289292
if (ArgEx)
290293
bugreporter::trackExpressionValue(N, ArgEx, *R);
@@ -302,23 +305,15 @@ bool CallAndMessageChecker::uninitRefOrPointer(
302305

303306
if (F.Find(D->getRegion())) {
304307
if (ExplodedNode *N = C.generateErrorNode()) {
305-
SmallString<512> Buf;
306-
llvm::raw_svector_ostream Os(Buf);
307-
Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
308-
<< " function call argument";
309-
if (ParamT->isPointerType())
310-
Os << " points to";
311-
else
312-
Os << " references";
313-
Os << " an uninitialized value";
314-
315-
F.printFieldChain(Os);
316-
317-
auto R = std::make_unique<PathSensitiveBugReport>(BT, Os.str(), N);
308+
std::string Msg = llvm::formatv(
309+
"{0}{1} function call argument {2} an uninitialized value {3}",
310+
(ArgumentNumber + 1), llvm::getOrdinalSuffix(ArgumentNumber + 1),
311+
ParamT->isPointerType() ? "points to" : "references", F.FieldChain);
312+
auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
318313
R->addRange(ArgRange);
319-
320314
if (ArgEx)
321315
bugreporter::trackExpressionValue(N, ArgEx, *R);
316+
322317
C.emitReport(std::move(R));
323318
}
324319
return true;
@@ -370,13 +365,12 @@ bool CallAndMessageChecker::PreVisitProcessArg(
370365
return true;
371366
}
372367
if (ExplodedNode *N = C.generateErrorNode()) {
373-
SmallString<512> Str;
374-
llvm::raw_svector_ostream os(Str);
375-
os << "Passed-by-value struct argument contains uninitialized data";
376-
F.printFieldChain(os);
368+
std::string Msg = llvm::formatv(
369+
"Passed-by-value struct argument contains uninitialized data {0}",
370+
F.FieldChain);
377371

378372
// Generate a report for this bug.
379-
auto R = std::make_unique<PathSensitiveBugReport>(BT, os.str(), N);
373+
auto R = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
380374
R->addRange(ArgRange);
381375

382376
if (ArgEx)

0 commit comments

Comments
 (0)