clang  14.0.0git
DynamicExtent.cpp
Go to the documentation of this file.
1 //===- DynamicExtent.cpp - Dynamic extent related APIs ----------*- 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 file defines APIs that track and query dynamic extent information.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "clang/AST/Expr.h"
15 #include "clang/Basic/LLVM.h"
21 
24 
25 namespace clang {
26 namespace ento {
27 
28 DefinedOrUnknownSVal getDynamicExtent(ProgramStateRef State,
29  const MemRegion *MR, SValBuilder &SVB) {
30  MR = MR->StripCasts();
31 
32  if (const DefinedOrUnknownSVal *Size = State->get<DynamicExtentMap>(MR))
33  return *Size;
34 
35  return MR->getMemRegionManager().getStaticSize(MR, SVB);
36 }
37 
38 DefinedOrUnknownSVal getElementExtent(QualType Ty, SValBuilder &SVB) {
39  return SVB.makeIntVal(SVB.getContext().getTypeSizeInChars(Ty).getQuantity(),
40  SVB.getArrayIndexType());
41 }
42 
43 DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State,
44  const MemRegion *MR,
45  SValBuilder &SVB,
46  QualType ElementTy) {
47  MR = MR->StripCasts();
48 
49  DefinedOrUnknownSVal Size = getDynamicExtent(State, MR, SVB);
50  SVal ElementSize = getElementExtent(ElementTy, SVB);
51 
52  SVal ElementCount =
53  SVB.evalBinOp(State, BO_Div, Size, ElementSize, SVB.getArrayIndexType());
54 
55  return ElementCount.castAs<DefinedOrUnknownSVal>();
56 }
57 
59  SValBuilder &SvalBuilder = State->getStateManager().getSValBuilder();
60  const MemRegion *MRegion = BufV.getAsRegion();
61  if (!MRegion)
62  return UnknownVal();
63  RegionOffset Offset = MRegion->getAsOffset();
64  if (Offset.hasSymbolicOffset())
65  return UnknownVal();
66  const MemRegion *BaseRegion = MRegion->getBaseRegion();
67  if (!BaseRegion)
68  return UnknownVal();
69 
70  NonLoc OffsetInBytes = SvalBuilder.makeArrayIndex(
71  Offset.getOffset() /
72  MRegion->getMemRegionManager().getContext().getCharWidth());
73  DefinedOrUnknownSVal ExtentInBytes =
74  getDynamicExtent(State, BaseRegion, SvalBuilder);
75 
76  return SvalBuilder.evalBinOp(State, BinaryOperator::Opcode::BO_Sub,
77  ExtentInBytes, OffsetInBytes,
78  SvalBuilder.getArrayIndexType());
79 }
80 
82  DefinedOrUnknownSVal Size, SValBuilder &SVB) {
83  MR = MR->StripCasts();
84 
85  if (Size.isUnknown())
86  return State;
87 
88  return State->set<DynamicExtentMap>(MR->StripCasts(), Size);
89 }
90 
91 } // namespace ento
92 } // namespace clang
DynamicExtent.h
SVals.h
clang::ento::DefinedOrUnknownSVal
Definition: SVals.h:236
clang::ento::ProgramStateRef
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
Definition: ProgramState_Fwd.h:37
REGISTER_MAP_WITH_PROGRAMSTATE
REGISTER_MAP_WITH_PROGRAMSTATE(DynamicExtentMap, const clang::ento::MemRegion *, clang::ento::DefinedOrUnknownSVal) namespace clang
Definition: DynamicExtent.cpp:22
SymbolManager.h
clang::ento::getDynamicExtentWithOffset
SVal getDynamicExtentWithOffset(ProgramStateRef State, SVal BufV)
Get the dynamic extent for a symbolic value that represents a buffer.
Offset
unsigned Offset
Definition: Format.cpp:2335
clang::ento::MemRegion
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:94
Expr.h
clang::ento::getDynamicElementCount
DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State, const MemRegion *MR, SValBuilder &SVB, QualType Ty)
clang::ento::getElementExtent
DefinedOrUnknownSVal getElementExtent(QualType Ty, SValBuilder &SVB)
SValBuilder.h
LLVM.h
State
LineState State
Definition: UnwrappedLineFormatter.cpp:986
ProgramState.h
clang::ento::getDynamicExtent
DefinedOrUnknownSVal getDynamicExtent(ProgramStateRef State, const MemRegion *MR, SValBuilder &SVB)
clang
Definition: CalledOnceCheck.h:17
MemRegion.h
clang::ento::setDynamicExtent
ProgramStateRef setDynamicExtent(ProgramStateRef State, const MemRegion *MR, DefinedOrUnknownSVal Extent, SValBuilder &SVB)
Set the dynamic extent Extent of the region MR.