1//===- DynamicSize.cpp - Dynamic size 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 size information. 10// 11//===----------------------------------------------------------------------===// 12 13#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h" 14#include "clang/AST/Expr.h" 15#include "clang/Basic/LLVM.h" 16#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" 17#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 18#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" 19#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 20#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" 21 22namespace clang { 23namespace ento { 24 25DefinedOrUnknownSVal getDynamicSize(ProgramStateRef State, const MemRegion *MR, 26 SValBuilder &SVB) { 27 return MR->getMemRegionManager().getStaticSize(MR, SVB); 28} 29 30DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State, 31 const MemRegion *MR, 32 SValBuilder &SVB, 33 QualType ElementTy) { 34 MemRegionManager &MemMgr = MR->getMemRegionManager(); 35 ASTContext &Ctx = MemMgr.getContext(); 36 37 DefinedOrUnknownSVal Size = getDynamicSize(State, MR, SVB); 38 SVal ElementSizeV = SVB.makeIntVal( 39 Ctx.getTypeSizeInChars(ElementTy).getQuantity(), SVB.getArrayIndexType()); 40 41 SVal DivisionV = 42 SVB.evalBinOp(State, BO_Div, Size, ElementSizeV, SVB.getArrayIndexType()); 43 44 return DivisionV.castAs<DefinedOrUnknownSVal>(); 45} 46 47SVal getDynamicSizeWithOffset(ProgramStateRef State, const SVal &BufV) { 48 SValBuilder &SvalBuilder = State->getStateManager().getSValBuilder(); 49 const MemRegion *MRegion = BufV.getAsRegion(); 50 if (!MRegion) 51 return UnknownVal(); 52 RegionOffset Offset = MRegion->getAsOffset(); 53 if (Offset.hasSymbolicOffset()) 54 return UnknownVal(); 55 const MemRegion *BaseRegion = MRegion->getBaseRegion(); 56 if (!BaseRegion) 57 return UnknownVal(); 58 59 NonLoc OffsetInBytes = SvalBuilder.makeArrayIndex( 60 Offset.getOffset() / 61 MRegion->getMemRegionManager().getContext().getCharWidth()); 62 DefinedOrUnknownSVal ExtentInBytes = 63 getDynamicSize(State, BaseRegion, SvalBuilder); 64 65 return SvalBuilder.evalBinOp(State, BinaryOperator::Opcode::BO_Sub, 66 ExtentInBytes, OffsetInBytes, 67 SvalBuilder.getArrayIndexType()); 68} 69 70} // namespace ento 71} // namespace clang 72