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

//===- SValBuilder.cpp - Basic class for all SValBuilder implementations --===//
//
// 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 SValBuilder, the base class for all (complete) SValBuilder
//  implementations.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Basic/LLVM.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include <cassert>
#include <optional>
#include <tuple>

usingnamespaceclang;
usingnamespaceento;

//===----------------------------------------------------------------------===//
// Basic SVal creation.
//===----------------------------------------------------------------------===//

void SValBuilder::anchor() {}

SValBuilder::SValBuilder(llvm::BumpPtrAllocator &alloc, ASTContext &context,
                         ProgramStateManager &stateMgr)
    :{}

DefinedOrUnknownSVal SValBuilder::makeZeroVal(QualType type) {}

nonloc::SymbolVal SValBuilder::makeNonLoc(const SymExpr *lhs,
                                          BinaryOperator::Opcode op,
                                          const llvm::APSInt &rhs,
                                          QualType type) {}

nonloc::SymbolVal SValBuilder::makeNonLoc(const llvm::APSInt &lhs,
                                          BinaryOperator::Opcode op,
                                          const SymExpr *rhs, QualType type) {}

nonloc::SymbolVal SValBuilder::makeNonLoc(const SymExpr *lhs,
                                          BinaryOperator::Opcode op,
                                          const SymExpr *rhs, QualType type) {}

NonLoc SValBuilder::makeNonLoc(const SymExpr *operand, UnaryOperator::Opcode op,
                               QualType type) {}

nonloc::SymbolVal SValBuilder::makeNonLoc(const SymExpr *operand,
                                          QualType fromTy, QualType toTy) {}

SVal SValBuilder::convertToArrayIndex(SVal val) {}

nonloc::ConcreteInt SValBuilder::makeBoolVal(const CXXBoolLiteralExpr *boolean){}

DefinedOrUnknownSVal
SValBuilder::getRegionValueSymbolVal(const TypedValueRegion *region) {}

DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *SymbolTag,
                                                   const Expr *Ex,
                                                   const LocationContext *LCtx,
                                                   unsigned Count) {}

DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const void *symbolTag,
                                                   const Stmt *St,
                                                   const LocationContext *LCtx,
                                                   QualType type,
                                                   unsigned count) {}

DefinedOrUnknownSVal SValBuilder::conjureSymbolVal(const Stmt *stmt,
                                                   const LocationContext *LCtx,
                                                   QualType type,
                                                   unsigned visitCount) {}

DefinedSVal SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
                                                  const LocationContext *LCtx,
                                                  unsigned VisitCount) {}

DefinedSVal SValBuilder::getConjuredHeapSymbolVal(const Expr *E,
                                                  const LocationContext *LCtx,
                                                  QualType type,
                                                  unsigned VisitCount) {}

loc::MemRegionVal SValBuilder::getAllocaRegionVal(const Expr *E,
                                                  const LocationContext *LCtx,
                                                  unsigned VisitCount) {}

DefinedSVal SValBuilder::getMetadataSymbolVal(const void *symbolTag,
                                              const MemRegion *region,
                                              const Expr *expr, QualType type,
                                              const LocationContext *LCtx,
                                              unsigned count) {}

DefinedOrUnknownSVal
SValBuilder::getDerivedRegionValueSymbolVal(SymbolRef parentSymbol,
                                             const TypedValueRegion *region) {}

DefinedSVal SValBuilder::getMemberPointer(const NamedDecl *ND) {}

DefinedSVal SValBuilder::getFunctionPointer(const FunctionDecl *func) {}

DefinedSVal SValBuilder::getBlockPointer(const BlockDecl *block,
                                         CanQualType locTy,
                                         const LocationContext *locContext,
                                         unsigned blockCount) {}

std::optional<loc::MemRegionVal>
SValBuilder::getCastedMemRegionVal(const MemRegion *R, QualType Ty) {}

/// Return a memory region for the 'this' object reference.
loc::MemRegionVal SValBuilder::getCXXThis(const CXXMethodDecl *D,
                                          const StackFrameContext *SFC) {}

/// Return a memory region for the 'this' object reference.
loc::MemRegionVal SValBuilder::getCXXThis(const CXXRecordDecl *D,
                                          const StackFrameContext *SFC) {}

std::optional<SVal> SValBuilder::getConstantVal(const Expr *E) {}

SVal SValBuilder::makeSymExprValNN(BinaryOperator::Opcode Op,
                                   NonLoc LHS, NonLoc RHS,
                                   QualType ResultTy) {}

SVal SValBuilder::evalMinus(NonLoc X) {}

SVal SValBuilder::evalComplement(NonLoc X) {}

SVal SValBuilder::evalUnaryOp(ProgramStateRef state, UnaryOperator::Opcode opc,
                 SVal operand, QualType type) {}

SVal SValBuilder::evalBinOp(ProgramStateRef state, BinaryOperator::Opcode op,
                            SVal lhs, SVal rhs, QualType type) {}

ConditionTruthVal SValBuilder::areEqual(ProgramStateRef state, SVal lhs,
                                        SVal rhs) {}

SVal SValBuilder::evalEQ(ProgramStateRef state, SVal lhs, SVal rhs) {}

DefinedOrUnknownSVal SValBuilder::evalEQ(ProgramStateRef state,
                                         DefinedOrUnknownSVal lhs,
                                         DefinedOrUnknownSVal rhs) {}

/// Recursively check if the pointer types are equal modulo const, volatile,
/// and restrict qualifiers. Also, assume that all types are similar to 'void'.
/// Assumes the input types are canonical.
static bool shouldBeModeledWithNoOp(ASTContext &Context, QualType ToTy,
                                                         QualType FromTy) {}

// Handles casts of type CK_IntegralCast.
// At the moment, this function will redirect to evalCast, except when the range
// of the original value is known to be greater than the max of the target type.
SVal SValBuilder::evalIntegralCast(ProgramStateRef state, SVal val,
                                   QualType castTy, QualType originalTy) {}

//===----------------------------------------------------------------------===//
// Cast method.
// `evalCast` and its helper `EvalCastVisitor`
//===----------------------------------------------------------------------===//

namespace {
class EvalCastVisitor : public SValVisitor<EvalCastVisitor, SVal> {};
} // end anonymous namespace

/// Cast a given SVal to another SVal using given QualType's.
/// \param V -- SVal that should be casted.
/// \param CastTy -- QualType that V should be casted according to.
/// \param OriginalTy -- QualType which is associated to V. It provides
/// additional information about what type the cast performs from.
/// \returns the most appropriate casted SVal.
/// Note: Many cases don't use an exact OriginalTy. It can be extracted
/// from SVal or the cast can performs unconditionaly. Always pass OriginalTy!
/// It can be crucial in certain cases and generates different results.
/// FIXME: If `OriginalTy.isNull()` is true, then cast performs based on CastTy
/// only. This behavior is uncertain and should be improved.
SVal SValBuilder::evalCast(SVal V, QualType CastTy, QualType OriginalTy) {}