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

//=== StdLibraryFunctionsChecker.cpp - Model standard 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 checker improves modeling of a few simple library functions.
//
// This checker provides a specification format - `Summary' - and
// contains descriptions of some library functions in this format. Each
// specification contains a list of branches for splitting the program state
// upon call, and range constraints on argument and return-value symbols that
// are satisfied on each branch. This spec can be expanded to include more
// items, like external effects of the function.
//
// The main difference between this approach and the body farms technique is
// in more explicit control over how many branches are produced. For example,
// consider standard C function `ispunct(int x)', which returns a non-zero value
// iff `x' is a punctuation character, that is, when `x' is in range
//   ['!', '/']   [':', '@']  U  ['[', '\`']  U  ['{', '~'].
// `Summary' provides only two branches for this function. However,
// any attempt to describe this range with if-statements in the body farm
// would result in many more branches. Because each branch needs to be analyzed
// independently, this significantly reduces performance. Additionally,
// once we consider a branch on which `x' is in range, say, ['!', '/'],
// we assume that such branch is an important separate path through the program,
// which may lead to false positives because considering this particular path
// was not consciously intended, and therefore it might have been unreachable.
//
// This checker uses eval::Call for modeling pure functions (functions without
// side effects), for which their `Summary' is a precise model. This avoids
// unnecessary invalidation passes. Conflicts with other checkers are unlikely
// because if the function has no other effects, other checkers would probably
// never want to improve upon the modeling done by this checker.
//
// Non-pure functions, for which only partial improvement over the default
// behavior is expected, are modeled via check::PostCall, non-intrusively.
//
//===----------------------------------------------------------------------===//

#include "ErrnoModeling.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.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/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicExtent.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/FormatVariadic.h"

#include <optional>
#include <string>

usingnamespaceclang;
usingnamespaceclang::ento;

namespace {
class StdLibraryFunctionsChecker
    : public Checker<check::PreCall, check::PostCall, eval::Call> {};

int StdLibraryFunctionsChecker::ErrnoConstraintBase::Tag =;

const StdLibraryFunctionsChecker::ArgNo StdLibraryFunctionsChecker::Ret =;

static BasicValueFactory &getBVF(ProgramStateRef State) {}

} // end of anonymous namespace

void StdLibraryFunctionsChecker::printArgDesc(
    StdLibraryFunctionsChecker::ArgNo ArgN, llvm::raw_ostream &Out) {}

void StdLibraryFunctionsChecker::printArgValueInfo(ArgNo ArgN,
                                                   ProgramStateRef State,
                                                   const CallEvent &Call,
                                                   llvm::raw_ostream &Out) {}

void StdLibraryFunctionsChecker::appendInsideRangeDesc(llvm::APSInt RMin,
                                                       llvm::APSInt RMax,
                                                       QualType ArgT,
                                                       BasicValueFactory &BVF,
                                                       llvm::raw_ostream &Out) {}

void StdLibraryFunctionsChecker::appendOutOfRangeDesc(llvm::APSInt RMin,
                                                      llvm::APSInt RMax,
                                                      QualType ArgT,
                                                      BasicValueFactory &BVF,
                                                      llvm::raw_ostream &Out) {}

void StdLibraryFunctionsChecker::RangeConstraint::applyOnWithinRange(
    BasicValueFactory &BVF, QualType ArgT, const RangeApplyFunction &F) const {}

void StdLibraryFunctionsChecker::RangeConstraint::applyOnOutOfRange(
    BasicValueFactory &BVF, QualType ArgT, const RangeApplyFunction &F) const {}

ProgramStateRef StdLibraryFunctionsChecker::RangeConstraint::apply(
    ProgramStateRef State, const CallEvent &Call, const Summary &Summary,
    CheckerContext &C) const {}

void StdLibraryFunctionsChecker::RangeConstraint::describe(
    DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
    const Summary &Summary, llvm::raw_ostream &Out) const {}

bool StdLibraryFunctionsChecker::RangeConstraint::describeArgumentValue(
    const CallEvent &Call, ProgramStateRef State, const Summary &Summary,
    llvm::raw_ostream &Out) const {}

ProgramStateRef StdLibraryFunctionsChecker::ComparisonConstraint::apply(
    ProgramStateRef State, const CallEvent &Call, const Summary &Summary,
    CheckerContext &C) const {}

ProgramStateRef StdLibraryFunctionsChecker::NotNullConstraint::apply(
    ProgramStateRef State, const CallEvent &Call, const Summary &Summary,
    CheckerContext &C) const {}

void StdLibraryFunctionsChecker::NotNullConstraint::describe(
    DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
    const Summary &Summary, llvm::raw_ostream &Out) const {}

bool StdLibraryFunctionsChecker::NotNullConstraint::describeArgumentValue(
    const CallEvent &Call, ProgramStateRef State, const Summary &Summary,
    llvm::raw_ostream &Out) const {}

ProgramStateRef StdLibraryFunctionsChecker::NotNullBufferConstraint::apply(
    ProgramStateRef State, const CallEvent &Call, const Summary &Summary,
    CheckerContext &C) const {}

void StdLibraryFunctionsChecker::NotNullBufferConstraint::describe(
    DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
    const Summary &Summary, llvm::raw_ostream &Out) const {}

bool StdLibraryFunctionsChecker::NotNullBufferConstraint::describeArgumentValue(
    const CallEvent &Call, ProgramStateRef State, const Summary &Summary,
    llvm::raw_ostream &Out) const {}

ProgramStateRef StdLibraryFunctionsChecker::BufferSizeConstraint::apply(
    ProgramStateRef State, const CallEvent &Call, const Summary &Summary,
    CheckerContext &C) const {}

void StdLibraryFunctionsChecker::BufferSizeConstraint::describe(
    DescriptionKind DK, const CallEvent &Call, ProgramStateRef State,
    const Summary &Summary, llvm::raw_ostream &Out) const {}

bool StdLibraryFunctionsChecker::BufferSizeConstraint::describeArgumentValue(
    const CallEvent &Call, ProgramStateRef State, const Summary &Summary,
    llvm::raw_ostream &Out) const {}

void StdLibraryFunctionsChecker::checkPreCall(const CallEvent &Call,
                                              CheckerContext &C) const {}

void StdLibraryFunctionsChecker::checkPostCall(const CallEvent &Call,
                                               CheckerContext &C) const {}

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

bool StdLibraryFunctionsChecker::Signature::matches(
    const FunctionDecl *FD) const {}

std::optional<StdLibraryFunctionsChecker::Summary>
StdLibraryFunctionsChecker::findFunctionSummary(const FunctionDecl *FD,
                                                CheckerContext &C) const {}

std::optional<StdLibraryFunctionsChecker::Summary>
StdLibraryFunctionsChecker::findFunctionSummary(const CallEvent &Call,
                                                CheckerContext &C) const {}

void StdLibraryFunctionsChecker::initFunctionSummaries(
    CheckerContext &C) const {}

void ento::registerStdCLibraryFunctionsChecker(CheckerManager &mgr) {}

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

void ento::registerStdCLibraryFunctionsTesterChecker(CheckerManager &mgr) {}

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