llvm/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp

//= CStringChecker.cpp - Checks calls to C string functions --------*- C++ -*-//
//
// 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 defines CStringChecker, which is an assortment of checks on calls
// to functions in <string.h>.
//
//===----------------------------------------------------------------------===//

#include "InterCheckerAPI.h"
#include "clang/AST/OperationKinds.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/CharInfo.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallDescription.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/raw_ostream.h"
#include <functional>
#include <optional>

usingnamespaceclang;
usingnamespaceento;
usingnamespacestd::placeholders;

namespace {
struct AnyArgExpr {};
struct SourceArgExpr : AnyArgExpr {};
struct DestinationArgExpr : AnyArgExpr {};
struct SizeArgExpr : AnyArgExpr {};

ErrorMessage;
enum class AccessKind {};

static ErrorMessage createOutOfBoundErrorMsg(StringRef FunctionDescription,
                                             AccessKind Access) {}

enum class ConcatFnKind {};

enum class CharKind {};
constexpr CharKind CK_Regular =;
constexpr CharKind CK_Wide =;

static QualType getCharPtrType(ASTContext &Ctx, CharKind CK) {}

class CStringChecker : public Checker< eval::Call,
                                         check::PreStmt<DeclStmt>,
                                         check::LiveSymbols,
                                         check::DeadSymbols,
                                         check::RegionChanges
                                         > {};

} //end anonymous namespace

REGISTER_MAP_WITH_PROGRAMSTATE()

//===----------------------------------------------------------------------===//
// Individual checks and utility methods.
//===----------------------------------------------------------------------===//

std::pair<ProgramStateRef, ProgramStateRef>
CStringChecker::assumeZero(CheckerContext &C, ProgramStateRef State, SVal V,
                           QualType Ty) {}

ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C,
                                             ProgramStateRef State,
                                             AnyArgExpr Arg, SVal l) const {}

static std::optional<NonLoc> getIndex(ProgramStateRef State,
                                      const ElementRegion *ER, CharKind CK) {}

// Basically 1 -> 1st, 12 -> 12th, etc.
static void printIdxWithOrdinalSuffix(llvm::raw_ostream &Os, unsigned Idx) {}

ProgramStateRef CStringChecker::checkInit(CheckerContext &C,
                                          ProgramStateRef State,
                                          AnyArgExpr Buffer, SVal Element,
                                          SVal Size) const {}

// FIXME: This was originally copied from ArrayBoundChecker.cpp. Refactor?
ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C,
                                              ProgramStateRef state,
                                              AnyArgExpr Buffer, SVal Element,
                                              AccessKind Access,
                                              CharKind CK) const {}

ProgramStateRef
CStringChecker::CheckBufferAccess(CheckerContext &C, ProgramStateRef State,
                                  AnyArgExpr Buffer, SizeArgExpr Size,
                                  AccessKind Access, CharKind CK) const {}

ProgramStateRef CStringChecker::CheckOverlap(CheckerContext &C,
                                             ProgramStateRef state,
                                             SizeArgExpr Size, AnyArgExpr First,
                                             AnyArgExpr Second,
                                             CharKind CK) const {}

void CStringChecker::emitOverlapBug(CheckerContext &C, ProgramStateRef state,
                                  const Stmt *First, const Stmt *Second) const {}

void CStringChecker::emitNullArgBug(CheckerContext &C, ProgramStateRef State,
                                    const Stmt *S, StringRef WarningMsg) const {}

void CStringChecker::emitUninitializedReadBug(CheckerContext &C,
                                              ProgramStateRef State,
                                              const Expr *E, const MemRegion *R,
                                              StringRef Msg) const {}

void CStringChecker::emitOutOfBoundsBug(CheckerContext &C,
                                        ProgramStateRef State, const Stmt *S,
                                        StringRef WarningMsg) const {}

void CStringChecker::emitNotCStringBug(CheckerContext &C, ProgramStateRef State,
                                       const Stmt *S,
                                       StringRef WarningMsg) const {}

void CStringChecker::emitAdditionOverflowBug(CheckerContext &C,
                                             ProgramStateRef State) const {}

ProgramStateRef CStringChecker::checkAdditionOverflow(CheckerContext &C,
                                                     ProgramStateRef state,
                                                     NonLoc left,
                                                     NonLoc right) const {}

ProgramStateRef CStringChecker::setCStringLength(ProgramStateRef state,
                                                const MemRegion *MR,
                                                SVal strLength) {}

SVal CStringChecker::getCStringLengthForRegion(CheckerContext &C,
                                               ProgramStateRef &state,
                                               const Expr *Ex,
                                               const MemRegion *MR,
                                               bool hypothetical) {}

SVal CStringChecker::getCStringLength(CheckerContext &C, ProgramStateRef &state,
                                      const Expr *Ex, SVal Buf,
                                      bool hypothetical) const {}

const StringLiteral *CStringChecker::getCStringLiteral(CheckerContext &C,
  ProgramStateRef &state, const Expr *expr, SVal val) const {}

bool CStringChecker::isFirstBufInBound(CheckerContext &C, ProgramStateRef State,
                                       SVal BufVal, QualType BufTy,
                                       SVal LengthVal, QualType LengthTy) {}

ProgramStateRef CStringChecker::invalidateDestinationBufferBySize(
    CheckerContext &C, ProgramStateRef S, const Expr *BufE, SVal BufV,
    SVal SizeV, QualType SizeTy) {}

ProgramStateRef
CStringChecker::invalidateDestinationBufferAlwaysEscapeSuperRegion(
    CheckerContext &C, ProgramStateRef S, const Expr *BufE, SVal BufV) {}

ProgramStateRef CStringChecker::invalidateDestinationBufferNeverOverflows(
    CheckerContext &C, ProgramStateRef S, const Expr *BufE, SVal BufV) {}

ProgramStateRef CStringChecker::invalidateSourceBuffer(CheckerContext &C,
                                                       ProgramStateRef S,
                                                       const Expr *BufE,
                                                       SVal BufV) {}

ProgramStateRef CStringChecker::invalidateBufferAux(
    CheckerContext &C, ProgramStateRef State, const Expr *E, SVal V,
    llvm::function_ref<bool(RegionAndSymbolInvalidationTraits &,
                            const MemRegion *)>
        InvalidationTraitOperations) {}

bool CStringChecker::SummarizeRegion(raw_ostream &os, ASTContext &Ctx,
                                     const MemRegion *MR) {}

bool CStringChecker::memsetAux(const Expr *DstBuffer, SVal CharVal,
                               const Expr *Size, CheckerContext &C,
                               ProgramStateRef &State) {}

//===----------------------------------------------------------------------===//
// evaluation of individual function calls.
//===----------------------------------------------------------------------===//

void CStringChecker::evalCopyCommon(CheckerContext &C, const CallEvent &Call,
                                    ProgramStateRef state, SizeArgExpr Size,
                                    DestinationArgExpr Dest,
                                    SourceArgExpr Source, bool Restricted,
                                    bool IsMempcpy, CharKind CK) const {}

void CStringChecker::evalMemcpy(CheckerContext &C, const CallEvent &Call,
                                CharKind CK) const {}

void CStringChecker::evalMempcpy(CheckerContext &C, const CallEvent &Call,
                                 CharKind CK) const {}

void CStringChecker::evalMemmove(CheckerContext &C, const CallEvent &Call,
                                 CharKind CK) const {}

void CStringChecker::evalBcopy(CheckerContext &C, const CallEvent &Call) const {}

void CStringChecker::evalMemcmp(CheckerContext &C, const CallEvent &Call,
                                CharKind CK) const {}

void CStringChecker::evalstrLength(CheckerContext &C,
                                   const CallEvent &Call) const {}

void CStringChecker::evalstrnLength(CheckerContext &C,
                                    const CallEvent &Call) const {}

void CStringChecker::evalstrLengthCommon(CheckerContext &C,
                                         const CallEvent &Call,
                                         bool IsStrnlen) const {}

void CStringChecker::evalStrcpy(CheckerContext &C,
                                const CallEvent &Call) const {}

void CStringChecker::evalStrncpy(CheckerContext &C,
                                 const CallEvent &Call) const {}

void CStringChecker::evalStpcpy(CheckerContext &C,
                                const CallEvent &Call) const {}

void CStringChecker::evalStrlcpy(CheckerContext &C,
                                 const CallEvent &Call) const {}

void CStringChecker::evalStrcat(CheckerContext &C,
                                const CallEvent &Call) const {}

void CStringChecker::evalStrncat(CheckerContext &C,
                                 const CallEvent &Call) const {}

void CStringChecker::evalStrlcat(CheckerContext &C,
                                 const CallEvent &Call) const {}

void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallEvent &Call,
                                      bool ReturnEnd, bool IsBounded,
                                      ConcatFnKind appendK,
                                      bool returnPtr) const {}

void CStringChecker::evalStrcmp(CheckerContext &C,
                                const CallEvent &Call) const {}

void CStringChecker::evalStrncmp(CheckerContext &C,
                                 const CallEvent &Call) const {}

void CStringChecker::evalStrcasecmp(CheckerContext &C,
                                    const CallEvent &Call) const {}

void CStringChecker::evalStrncasecmp(CheckerContext &C,
                                     const CallEvent &Call) const {}

void CStringChecker::evalStrcmpCommon(CheckerContext &C, const CallEvent &Call,
                                      bool IsBounded, bool IgnoreCase) const {}

void CStringChecker::evalStrsep(CheckerContext &C,
                                const CallEvent &Call) const {}

// These should probably be moved into a C++ standard library checker.
void CStringChecker::evalStdCopy(CheckerContext &C,
                                 const CallEvent &Call) const {}

void CStringChecker::evalStdCopyBackward(CheckerContext &C,
                                         const CallEvent &Call) const {}

void CStringChecker::evalStdCopyCommon(CheckerContext &C,
                                       const CallEvent &Call) const {}

void CStringChecker::evalMemset(CheckerContext &C,
                                const CallEvent &Call) const {}

void CStringChecker::evalBzero(CheckerContext &C, const CallEvent &Call) const {}

void CStringChecker::evalSprintf(CheckerContext &C,
                                 const CallEvent &Call) const {}

void CStringChecker::evalSnprintf(CheckerContext &C,
                                  const CallEvent &Call) const {}

void CStringChecker::evalSprintfCommon(CheckerContext &C, const CallEvent &Call,
                                       bool IsBounded) const {}

//===----------------------------------------------------------------------===//
// The driver method, and other Checker callbacks.
//===----------------------------------------------------------------------===//

CStringChecker::FnCheck CStringChecker::identifyCall(const CallEvent &Call,
                                                     CheckerContext &C) const {}

bool CStringChecker::evalCall(const CallEvent &Call, CheckerContext &C) const {}

void CStringChecker::checkPreStmt(const DeclStmt *DS, CheckerContext &C) const {}

ProgramStateRef
CStringChecker::checkRegionChanges(ProgramStateRef state,
    const InvalidatedSymbols *,
    ArrayRef<const MemRegion *> ExplicitRegions,
    ArrayRef<const MemRegion *> Regions,
    const LocationContext *LCtx,
    const CallEvent *Call) const {}

void CStringChecker::checkLiveSymbols(ProgramStateRef state,
    SymbolReaper &SR) const {}

void CStringChecker::checkDeadSymbols(SymbolReaper &SR,
    CheckerContext &C) const {}

void ento::registerCStringModeling(CheckerManager &Mgr) {}

bool ento::shouldRegisterCStringModeling(const CheckerManager &mgr) {}

#define REGISTER_CHECKER(name)

REGISTER_CHECKER(CStringNullArg)
REGISTER_CHECKER(CStringOutOfBounds)
REGISTER_CHECKER(CStringBufferOverlap)
REGISTER_CHECKER(CStringNotNullTerm)
REGISTER_CHECKER(CStringUninitializedRead)