Coverage Report

Created: 2023-09-30 09:22

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/StaticAnalyzer/Checkers/UndefinedNewArraySizeChecker.cpp
Line
Count
Source
1
//===--- UndefinedNewArraySizeChecker.cpp -----------------------*- 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
// This defines UndefinedNewArraySizeChecker, a builtin check in ExprEngine
10
// that checks if the size of the array in a new[] expression is undefined.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
15
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
16
#include "clang/StaticAnalyzer/Core/Checker.h"
17
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
18
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
19
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
20
21
using namespace clang;
22
using namespace ento;
23
24
namespace {
25
class UndefinedNewArraySizeChecker : public Checker<check::PreCall> {
26
27
private:
28
  BugType BT{this, "Undefined array element count in new[]",
29
             categories::LogicError};
30
31
public:
32
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
33
  void HandleUndefinedArrayElementCount(CheckerContext &C, SVal ArgVal,
34
                                        const Expr *Init,
35
                                        SourceRange Range) const;
36
};
37
} // namespace
38
39
void UndefinedNewArraySizeChecker::checkPreCall(const CallEvent &Call,
40
83.9k
                                                CheckerContext &C) const {
41
83.9k
  if (const auto *AC = dyn_cast<CXXAllocatorCall>(&Call)) {
42
1.04k
    if (!AC->isArray())
43
874
      return;
44
45
175
    auto *SizeEx = *AC->getArraySizeExpr();
46
175
    auto SizeVal = AC->getArraySizeVal();
47
48
175
    if (SizeVal.isUndef())
49
7
      HandleUndefinedArrayElementCount(C, SizeVal, SizeEx,
50
7
                                       SizeEx->getSourceRange());
51
175
  }
52
83.9k
}
53
54
void UndefinedNewArraySizeChecker::HandleUndefinedArrayElementCount(
55
7
    CheckerContext &C, SVal ArgVal, const Expr *Init, SourceRange Range) const {
56
57
7
  if (ExplodedNode *N = C.generateErrorNode()) {
58
59
7
    SmallString<100> buf;
60
7
    llvm::raw_svector_ostream os(buf);
61
62
7
    os << "Element count in new[] is a garbage value";
63
64
7
    auto R = std::make_unique<PathSensitiveBugReport>(BT, os.str(), N);
65
7
    R->markInteresting(ArgVal);
66
7
    R->addRange(Range);
67
7
    bugreporter::trackExpressionValue(N, Init, *R);
68
69
7
    C.emitReport(std::move(R));
70
7
  }
71
7
}
72
73
773
void ento::registerUndefinedNewArraySizeChecker(CheckerManager &mgr) {
74
773
  mgr.registerChecker<UndefinedNewArraySizeChecker>();
75
773
}
76
77
bool ento::shouldRegisterUndefinedNewArraySizeChecker(
78
2.55k
    const CheckerManager &mgr) {
79
2.55k
  return mgr.getLangOpts().CPlusPlus;
80
2.55k
}