llvm/clang/lib/StaticAnalyzer/Core/MemRegion.cpp

//===- MemRegion.cpp - Abstract memory regions for static analysis --------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  This file defines MemRegion and its subclasses.  MemRegion defines a
//  partially-typed abstraction of memory useful for path-sensitive dataflow
//  analyses.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/Support/BumpVector.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceManager.h"
#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CheckedArithmetic.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
#include <functional>
#include <iterator>
#include <optional>
#include <string>
#include <tuple>
#include <utility>

usingnamespaceclang;
usingnamespaceento;

#define DEBUG_TYPE

//===----------------------------------------------------------------------===//
// MemRegion Construction.
//===----------------------------------------------------------------------===//

template <typename RegionTy, typename SuperTy, typename Arg1Ty>
RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1,
                                         const SuperTy *superRegion) {}

template <typename RegionTy, typename SuperTy, typename Arg1Ty, typename Arg2Ty>
RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
                                         const SuperTy *superRegion) {}

template <typename RegionTy, typename SuperTy,
          typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
                                         const Arg3Ty arg3,
                                         const SuperTy *superRegion) {}

//===----------------------------------------------------------------------===//
// Object destruction.
//===----------------------------------------------------------------------===//

MemRegion::~MemRegion() = default;

// All regions and their data are BumpPtrAllocated.  No need to call their
// destructors.
MemRegionManager::~MemRegionManager() = default;

//===----------------------------------------------------------------------===//
// Basic methods.
//===----------------------------------------------------------------------===//

bool SubRegion::isSubRegionOf(const MemRegion* R) const {}

MemRegionManager &SubRegion::getMemRegionManager() const {}

const StackFrameContext *VarRegion::getStackFrame() const {}

const StackFrameContext *
CXXLifetimeExtendedObjectRegion::getStackFrame() const {}

const StackFrameContext *CXXTempObjectRegion::getStackFrame() const {}

ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg)
    :{}

const ObjCIvarDecl *ObjCIvarRegion::getDecl() const {}

QualType ObjCIvarRegion::getValueType() const {}

QualType CXXBaseObjectRegion::getValueType() const {}

QualType CXXDerivedObjectRegion::getValueType() const {}

QualType ParamVarRegion::getValueType() const {}

const ParmVarDecl *ParamVarRegion::getDecl() const {}

//===----------------------------------------------------------------------===//
// FoldingSet profiling.
//===----------------------------------------------------------------------===//

void MemSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

void StringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                 const StringLiteral *Str,
                                 const MemRegion *superRegion) {}

void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                     const ObjCStringLiteral *Str,
                                     const MemRegion *superRegion) {}

void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                 const Expr *Ex, unsigned cnt,
                                 const MemRegion *superRegion) {}

void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {}

void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {}

void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                          const CompoundLiteralExpr *CL,
                                          const MemRegion* superRegion) {}

void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                  const PointerType *PT,
                                  const MemRegion *sRegion) {}

void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

void FieldRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                   const ObjCIvarDecl *ivd,
                                   const MemRegion* superRegion) {}

void ObjCIvarRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

void NonParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                      const VarDecl *VD,
                                      const MemRegion *superRegion) {}

void NonParamVarRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

void ParamVarRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE,
                                   unsigned Idx, const MemRegion *SReg) {}

void ParamVarRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
                                   const MemRegion *sreg) {}

void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {}

void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                  QualType ElementType, SVal Idx,
                                  const MemRegion* superRegion) {}

void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {}

void FunctionCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                       const NamedDecl *FD,
                                       const MemRegion*) {}

void FunctionCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {}

void BlockCodeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                    const BlockDecl *BD, CanQualType,
                                    const AnalysisDeclContext *AC,
                                    const MemRegion*) {}

void BlockCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {}

void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
                                    const BlockCodeRegion *BC,
                                    const LocationContext *LC,
                                    unsigned BlkCount,
                                    const MemRegion *sReg) {}

void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {}

void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                        Expr const *Ex,
                                        const MemRegion *sReg) {}

void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

void CXXLifetimeExtendedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                                    const Expr *E,
                                                    const ValueDecl *D,
                                                    const MemRegion *sReg) {}

void CXXLifetimeExtendedObjectRegion::Profile(
    llvm::FoldingSetNodeID &ID) const {}

void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                        const CXXRecordDecl *RD,
                                        bool IsVirtual,
                                        const MemRegion *SReg) {}

void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

void CXXDerivedObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
                                           const CXXRecordDecl *RD,
                                           const MemRegion *SReg) {}

void CXXDerivedObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {}

//===----------------------------------------------------------------------===//
// Region anchors.
//===----------------------------------------------------------------------===//

void GlobalsSpaceRegion::anchor() {}

void NonStaticGlobalSpaceRegion::anchor() {}

void StackSpaceRegion::anchor() {}

void TypedRegion::anchor() {}

void TypedValueRegion::anchor() {}

void CodeTextRegion::anchor() {}

void SubRegion::anchor() {}

//===----------------------------------------------------------------------===//
// Region pretty-printing.
//===----------------------------------------------------------------------===//

LLVM_DUMP_METHOD void MemRegion::dump() const {}

std::string MemRegion::getString() const {}

void MemRegion::dumpToStream(raw_ostream &os) const {}

void AllocaRegion::dumpToStream(raw_ostream &os) const {}

void FunctionCodeRegion::dumpToStream(raw_ostream &os) const {}

void BlockCodeRegion::dumpToStream(raw_ostream &os) const {}

void BlockDataRegion::dumpToStream(raw_ostream &os) const {}

void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const {}

void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const {}

void CXXLifetimeExtendedObjectRegion::dumpToStream(raw_ostream &os) const {}

void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const {}

void CXXDerivedObjectRegion::dumpToStream(raw_ostream &os) const {}

void CXXThisRegion::dumpToStream(raw_ostream &os) const {}

void ElementRegion::dumpToStream(raw_ostream &os) const {}

void FieldRegion::dumpToStream(raw_ostream &os) const {}

void ObjCIvarRegion::dumpToStream(raw_ostream &os) const {}

void StringRegion::dumpToStream(raw_ostream &os) const {}

void ObjCStringRegion::dumpToStream(raw_ostream &os) const {}

void SymbolicRegion::dumpToStream(raw_ostream &os) const {}

void NonParamVarRegion::dumpToStream(raw_ostream &os) const {}

LLVM_DUMP_METHOD void RegionRawOffset::dump() const {}

void RegionRawOffset::dumpToStream(raw_ostream &os) const {}

void CodeSpaceRegion::dumpToStream(raw_ostream &os) const {}

void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const {}

void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const {}

void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const {}

void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const {}

void HeapSpaceRegion::dumpToStream(raw_ostream &os) const {}

void UnknownSpaceRegion::dumpToStream(raw_ostream &os) const {}

void StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const {}

void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const {}

void ParamVarRegion::dumpToStream(raw_ostream &os) const {}

bool MemRegion::canPrintPretty() const {}

bool MemRegion::canPrintPrettyAsExpr() const {}

StringRef MemRegion::getKindStr() const {}

void MemRegion::printPretty(raw_ostream &os) const {}

void MemRegion::printPrettyAsExpr(raw_ostream &) const {}

bool NonParamVarRegion::canPrintPrettyAsExpr() const {}

void NonParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {}

bool ParamVarRegion::canPrintPrettyAsExpr() const {}

void ParamVarRegion::printPrettyAsExpr(raw_ostream &os) const {}

bool ObjCIvarRegion::canPrintPrettyAsExpr() const {}

void ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const {}

bool FieldRegion::canPrintPretty() const {}

bool FieldRegion::canPrintPrettyAsExpr() const {}

void FieldRegion::printPrettyAsExpr(raw_ostream &os) const {}

void FieldRegion::printPretty(raw_ostream &os) const {}

bool CXXBaseObjectRegion::canPrintPrettyAsExpr() const {}

void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const {}

bool CXXDerivedObjectRegion::canPrintPrettyAsExpr() const {}

void CXXDerivedObjectRegion::printPrettyAsExpr(raw_ostream &os) const {}

std::string MemRegion::getDescriptiveName(bool UseQuotes) const {}

SourceRange MemRegion::sourceRange() const {}

//===----------------------------------------------------------------------===//
// MemRegionManager methods.
//===----------------------------------------------------------------------===//

DefinedOrUnknownSVal MemRegionManager::getStaticSize(const MemRegion *MR,
                                                     SValBuilder &SVB) const {}

template <typename REG>
const REG *MemRegionManager::LazyAllocate(REG*& region) {}

template <typename REG, typename ARG>
const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {}

const StackLocalsSpaceRegion*
MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {}

const StackArgumentsSpaceRegion *
MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {}

const GlobalsSpaceRegion
*MemRegionManager::getGlobalsRegion(MemRegion::Kind K,
                                    const CodeTextRegion *CR) {}

const HeapSpaceRegion *MemRegionManager::getHeapRegion() {}

const UnknownSpaceRegion *MemRegionManager::getUnknownRegion() {}

const CodeSpaceRegion *MemRegionManager::getCodeRegion() {}

//===----------------------------------------------------------------------===//
// Constructing regions.
//===----------------------------------------------------------------------===//

const StringRegion *MemRegionManager::getStringRegion(const StringLiteral *Str){}

const ObjCStringRegion *
MemRegionManager::getObjCStringRegion(const ObjCStringLiteral *Str){}

/// Look through a chain of LocationContexts to either find the
/// StackFrameContext that matches a DeclContext, or find a VarRegion
/// for a variable captured by a block.
static llvm::PointerUnion<const StackFrameContext *, const VarRegion *>
getStackOrCaptureRegionForDeclContext(const LocationContext *LC,
                                      const DeclContext *DC,
                                      const VarDecl *VD) {}

const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
                                                const LocationContext *LC) {}

const NonParamVarRegion *
MemRegionManager::getNonParamVarRegion(const VarDecl *D,
                                       const MemRegion *superR) {}

const ParamVarRegion *
MemRegionManager::getParamVarRegion(const Expr *OriginExpr, unsigned Index,
                                    const LocationContext *LC) {}

const BlockDataRegion *
MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC,
                                     const LocationContext *LC,
                                     unsigned blockCount) {}

const CompoundLiteralRegion*
MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
                                           const LocationContext *LC) {}

const ElementRegion *
MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
                                   const SubRegion *superRegion,
                                   const ASTContext &Ctx) {}

const FunctionCodeRegion *
MemRegionManager::getFunctionCodeRegion(const NamedDecl *FD) {}

const BlockCodeRegion *
MemRegionManager::getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy,
                                     AnalysisDeclContext *AC) {}

const SymbolicRegion *
MemRegionManager::getSymbolicRegion(SymbolRef sym,
                                    const MemSpaceRegion *MemSpace) {}

const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {}

const FieldRegion*
MemRegionManager::getFieldRegion(const FieldDecl *d,
                                 const SubRegion* superRegion){}

const ObjCIvarRegion*
MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
                                    const SubRegion* superRegion) {}

const CXXTempObjectRegion*
MemRegionManager::getCXXTempObjectRegion(Expr const *E,
                                         LocationContext const *LC) {}

const CXXLifetimeExtendedObjectRegion *
MemRegionManager::getCXXLifetimeExtendedObjectRegion(
    const Expr *Ex, const ValueDecl *VD, const LocationContext *LC) {}

const CXXLifetimeExtendedObjectRegion *
MemRegionManager::getCXXStaticLifetimeExtendedObjectRegion(
    const Expr *Ex, const ValueDecl *VD) {}

/// Checks whether \p BaseClass is a valid virtual or direct non-virtual base
/// class of the type of \p Super.
static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
                             const TypedValueRegion *Super,
                             bool IsVirtual) {}

const CXXBaseObjectRegion *
MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
                                         const SubRegion *Super,
                                         bool IsVirtual) {}

const CXXDerivedObjectRegion *
MemRegionManager::getCXXDerivedObjectRegion(const CXXRecordDecl *RD,
                                            const SubRegion *Super) {}

const CXXThisRegion*
MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
                                   const LocationContext *LC) {}

const AllocaRegion*
MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt,
                                  const LocationContext *LC) {}

const MemSpaceRegion *MemRegion::getMemorySpace() const {}

bool MemRegion::hasStackStorage() const {}

bool MemRegion::hasStackNonParametersStorage() const {}

bool MemRegion::hasStackParametersStorage() const {}

// Strips away all elements and fields.
// Returns the base region of them.
const MemRegion *MemRegion::getBaseRegion() const {}

// Returns the region of the root class of a C++ class hierarchy.
const MemRegion *MemRegion::getMostDerivedObjectRegion() const {}

bool MemRegion::isSubRegionOf(const MemRegion *) const {}

//===----------------------------------------------------------------------===//
// View handling.
//===----------------------------------------------------------------------===//

const MemRegion *MemRegion::StripCasts(bool StripBaseAndDerivedCasts) const {}

const SymbolicRegion *MemRegion::getSymbolicBase() const {}

RegionRawOffset ElementRegion::getAsArrayOffset() const {}

/// Returns true if \p Base is an immediate base class of \p Child
static bool isImmediateBase(const CXXRecordDecl *Child,
                            const CXXRecordDecl *Base) {}

static RegionOffset calculateOffset(const MemRegion *R) {}

RegionOffset MemRegion::getAsOffset() const {}

//===----------------------------------------------------------------------===//
// BlockDataRegion
//===----------------------------------------------------------------------===//

std::pair<const VarRegion *, const VarRegion *>
BlockDataRegion::getCaptureRegions(const VarDecl *VD) {}

void BlockDataRegion::LazyInitializeReferencedVars() {}

BlockDataRegion::referenced_vars_iterator
BlockDataRegion::referenced_vars_begin() const {}

BlockDataRegion::referenced_vars_iterator
BlockDataRegion::referenced_vars_end() const {}

llvm::iterator_range<BlockDataRegion::referenced_vars_iterator>
BlockDataRegion::referenced_vars() const {}

const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const {}

//===----------------------------------------------------------------------===//
// RegionAndSymbolInvalidationTraits
//===----------------------------------------------------------------------===//

void RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym,
                                                 InvalidationKinds IK) {}

void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR,
                                                 InvalidationKinds IK) {}

bool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym,
                                                 InvalidationKinds IK) const {}

bool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR,
                                                 InvalidationKinds IK) const {}