1 //===--- UndefinedNewArraySizeChecker.cpp -----------------------*- C++ -*--==//
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
7 //===----------------------------------------------------------------------===//
9 // This defines UndefinedNewArraySizeChecker, a builtin check in ExprEngine
10 // that checks if the size of the array in a new[] expression is undefined.
12 //===----------------------------------------------------------------------===//
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"
21 using namespace clang
;
25 class UndefinedNewArraySizeChecker
: public Checker
<check::PreCall
> {
28 BugType BT
{this, "Undefined array element count in new[]",
29 categories::LogicError
};
32 void checkPreCall(const CallEvent
&Call
, CheckerContext
&C
) const;
33 void HandleUndefinedArrayElementCount(CheckerContext
&C
, SVal ArgVal
,
35 SourceRange Range
) const;
39 void UndefinedNewArraySizeChecker::checkPreCall(const CallEvent
&Call
,
40 CheckerContext
&C
) const {
41 if (const auto *AC
= dyn_cast
<CXXAllocatorCall
>(&Call
)) {
45 auto *SizeEx
= *AC
->getArraySizeExpr();
46 auto SizeVal
= AC
->getArraySizeVal();
48 if (SizeVal
.isUndef())
49 HandleUndefinedArrayElementCount(C
, SizeVal
, SizeEx
,
50 SizeEx
->getSourceRange());
54 void UndefinedNewArraySizeChecker::HandleUndefinedArrayElementCount(
55 CheckerContext
&C
, SVal ArgVal
, const Expr
*Init
, SourceRange Range
) const {
57 if (ExplodedNode
*N
= C
.generateErrorNode()) {
60 llvm::raw_svector_ostream
os(buf
);
62 os
<< "Element count in new[] is a garbage value";
64 auto R
= std::make_unique
<PathSensitiveBugReport
>(BT
, os
.str(), N
);
65 R
->markInteresting(ArgVal
);
67 bugreporter::trackExpressionValue(N
, Init
, *R
);
69 C
.emitReport(std::move(R
));
73 void ento::registerUndefinedNewArraySizeChecker(CheckerManager
&mgr
) {
74 mgr
.registerChecker
<UndefinedNewArraySizeChecker
>();
77 bool ento::shouldRegisterUndefinedNewArraySizeChecker(
78 const CheckerManager
&mgr
) {
79 return mgr
.getLangOpts().CPlusPlus
;