clang 22.0.0git
UnsafeBufferUsage.cpp File Reference
#include "clang/Analysis/Analyses/UnsafeBufferUsage.h"
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/AST/Expr.h"
#include "clang/AST/FormatString.h"
#include "clang/AST/ParentMapContext.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/Type.h"
#include "clang/ASTMatchers/LowLevelHelpers.h"
#include "clang/Analysis/Support/FixitUtil.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include <cstddef>
#include <optional>
#include <queue>
#include <set>
#include <sstream>
#include "clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def"

Go to the source code of this file.

Classes

class  MatchDescendantVisitor
struct  libc_func_matchers::LibcFunNamePrefixSuffixParser
class  UPCPreIncrementGadget
class  UUCAddAssignGadget
class  DerefSimplePtrArithFixableGadget
class  WarningGadgetMatcher
class  FixableGadgetMatcher
struct  CompareNode< NodeTy >
struct  WarningGadgetSets
struct  FixableGadgetSets
class  VariableGroupsManagerImpl

Namespaces

namespace  libc_func_matchers

Macros

#define SIZED_CONTAINER_OR_VIEW_LIST
#define GADGET(x)
#define GADGET(x)
#define WARNING_GADGET(name)
#define WARNING_OPTIONAL_GADGET(name)
#define FIXABLE_GADGET(name)
#define DEBUG_NOTE_DECL_FAIL(D, Msg)

Functions

static bool hasPointerType (const Expr &E)
static bool hasArrayType (const Expr &E)
static void forEachDescendantEvaluatedStmt (const Stmt *S, ASTContext &Ctx, const UnsafeBufferUsageHandler &Handler, FastMatcher &Matcher)
static void forEachDescendantStmt (const Stmt *S, ASTContext &Ctx, const UnsafeBufferUsageHandler &Handler, FastMatcher &Matcher)
static bool notInSafeBufferOptOut (const Stmt &Node, const UnsafeBufferUsageHandler *Handler)
static bool ignoreUnsafeBufferInContainer (const Stmt &Node, const UnsafeBufferUsageHandler *Handler)
static bool ignoreUnsafeLibcCall (const ASTContext &Ctx, const Stmt &Node, const UnsafeBufferUsageHandler *Handler)
static void findStmtsInUnspecifiedLvalueContext (const Stmt *S, const llvm::function_ref< void(const Expr *)> OnResult)
static void findStmtsInUnspecifiedPointerContext (const Stmt *S, llvm::function_ref< void(const Stmt *)> InnerMatcher)
static void findStmtsInUnspecifiedUntypedContext (const Stmt *S, llvm::function_ref< void(const Stmt *)> InnerMatcher)
static bool areEqualIntegers (const Expr *E1, const Expr *E2, ASTContext &Ctx)
static bool areEqualIntegralBinaryOperators (const BinaryOperator *E1, const Expr *E2_LHS, BinaryOperatorKind BOP, const Expr *E2_RHS, ASTContext &Ctx)
static bool isPtrBufferSafe (const Expr *Ptr, const Expr *Size, ASTContext &Ctx)
static bool isSafeSpanTwoParamConstruct (const CXXConstructExpr &Node, ASTContext &Ctx)
static bool isSafeArraySubscript (const ArraySubscriptExpr &Node, const ASTContext &Ctx)
static bool libc_func_matchers::isNullTermPointer (const Expr *Ptr)
static bool libc_func_matchers::hasUnsafeFormatOrSArg (const CallExpr *Call, const Expr *&UnsafeArg, const unsigned FmtArgIdx, ASTContext &Ctx, bool isKprintf=false)
static bool libc_func_matchers::isPredefinedUnsafeLibcFunc (const FunctionDecl &Node)
static bool libc_func_matchers::isUnsafeVaListPrintfFunc (const FunctionDecl &Node)
static bool libc_func_matchers::isUnsafeSprintfFunc (const FunctionDecl &Node)
static bool libc_func_matchers::isNormalPrintfFunc (const FunctionDecl &Node)
static bool libc_func_matchers::hasUnsafePrintfStringArg (const CallExpr &Node, ASTContext &Ctx, MatchResult &Result, llvm::StringRef Tag)
static bool libc_func_matchers::hasUnsafeSnprintfBuffer (const CallExpr &Node, ASTContext &Ctx)
static void findGadgets (const Stmt *S, ASTContext &Ctx, const UnsafeBufferUsageHandler &Handler, bool EmitSuggestions, FixableGadgetList &FixableGadgets, WarningGadgetList &WarningGadgets, DeclUseTracker &Tracker)
static WarningGadgetSets groupWarningGadgetsByVar (const WarningGadgetList &AllUnsafeOperations)
static FixableGadgetSets groupFixablesByVar (FixableGadgetList &&AllFixableOperations)
static std::optional< FixItList > createDataFixit (const ASTContext &Ctx, const DeclRefExpr *DRE)
static bool isNonNegativeIntegerExpr (const Expr *Expr, const VarDecl *VD, const ASTContext &Ctx)
static std::optional< FixItList > fixUPCAddressofArraySubscriptWithSpan (const UnaryOperator *Node)
static StringRef getEndOfLine ()
static std::string getUserFillPlaceHolder (StringRef HintTextToUser="placeholder")
template<typename NodeTy>
static std::optional< SourceLocationgetEndCharLoc (const NodeTy *Node, const SourceManager &SM, const LangOptions &LangOpts)
static bool hasUnsupportedSpecifiers (const VarDecl *VD, const SourceManager &SM)
static SourceRange getSourceRangeToTokenEnd (const Decl *D, const SourceManager &SM, const LangOptions &LangOpts)
static std::optional< StringRef > getFunNameText (const FunctionDecl *FD, const SourceManager &SM, const LangOptions &LangOpts)
static std::string getSpanTypeText (StringRef EltTyText, std::optional< Qualifiers > Quals=std::nullopt)
static std::optional< FixItList > FixVarInitializerWithSpan (const Expr *Init, ASTContext &Ctx, const StringRef UserFillPlaceHolder)
static std::optional< std::string > createSpanTypeForVarDecl (const VarDecl *VD, const ASTContext &Ctx)
static FixItList fixLocalVarDeclWithSpan (const VarDecl *D, ASTContext &Ctx, const StringRef UserFillPlaceHolder, UnsafeBufferUsageHandler &Handler)
static bool hasConflictingOverload (const FunctionDecl *FD)
static std::optional< FixItList > createOverloadsForFixedParams (const FixitStrategy &S, const FunctionDecl *FD, const ASTContext &Ctx, UnsafeBufferUsageHandler &Handler)
static FixItList fixParamWithSpan (const ParmVarDecl *PVD, const ASTContext &Ctx, UnsafeBufferUsageHandler &Handler)
static FixItList fixVariableWithSpan (const VarDecl *VD, const DeclUseTracker &Tracker, ASTContext &Ctx, UnsafeBufferUsageHandler &Handler)
static FixItList fixVarDeclWithArray (const VarDecl *D, const ASTContext &Ctx, UnsafeBufferUsageHandler &Handler)
static FixItList fixVariableWithArray (const VarDecl *VD, const DeclUseTracker &Tracker, const ASTContext &Ctx, UnsafeBufferUsageHandler &Handler)
static FixItList fixVariable (const VarDecl *VD, FixitStrategy::Kind K, const Decl *D, const DeclUseTracker &Tracker, ASTContext &Ctx, UnsafeBufferUsageHandler &Handler)
static bool overlapWithMacro (const FixItList &FixIts)
static bool isParameterOf (const VarDecl *VD, const Decl *D)
static void eraseVarsForUnfixableGroupMates (std::map< const VarDecl *, FixItList > &FixItsForVariable, const VariableGroupsManager &VarGrpMgr)
static FixItList createFunctionOverloadsForParms (std::map< const VarDecl *, FixItList > &FixItsForVariable, const VariableGroupsManager &VarGrpMgr, const FunctionDecl *FD, const FixitStrategy &S, ASTContext &Ctx, UnsafeBufferUsageHandler &Handler)
static std::map< const VarDecl *, FixItList > getFixIts (FixableGadgetSets &FixablesForAllVars, const FixitStrategy &S, ASTContext &Ctx, const Decl *D, const DeclUseTracker &Tracker, UnsafeBufferUsageHandler &Handler, const VariableGroupsManager &VarGrpMgr)
template<typename VarDeclIterTy>
static FixitStrategy getNaiveStrategy (llvm::iterator_range< VarDeclIterTy > UnsafeVars)
static void applyGadgets (const Decl *D, FixableGadgetList FixableGadgets, WarningGadgetList WarningGadgets, DeclUseTracker Tracker, UnsafeBufferUsageHandler &Handler, bool EmitSuggestions)

Macro Definition Documentation

◆ DEBUG_NOTE_DECL_FAIL

#define DEBUG_NOTE_DECL_FAIL ( D,
Msg )
Value:
Handler.addDebugNoteForVar((D), (D)->getBeginLoc(), \
"failed to produce fixit for declaration '" + \
(D)->getNameAsString() + "'" + (Msg))

Definition at line 3321 of file UnsafeBufferUsage.cpp.

Referenced by fixLocalVarDeclWithSpan(), fixParamWithSpan(), fixVarDeclWithArray(), fixVariable(), and fixVariableWithSpan().

◆ FIXABLE_GADGET

#define FIXABLE_GADGET ( name)
Value:
if (name##Gadget::matches(S, Results)) { \
for (const auto &R : Results) { \
FixableGadgets.push_back(std::make_unique<name##Gadget>(R)); \
matchFound = true; \
} \
Results = {}; \
}

◆ GADGET [1/2]

#define GADGET ( x)
Value:
x,

Definition at line 1234 of file UnsafeBufferUsage.cpp.

◆ GADGET [2/2]

#define GADGET ( x)
Value:
case Kind::x: \
return #x;

Definition at line 1234 of file UnsafeBufferUsage.cpp.

◆ SIZED_CONTAINER_OR_VIEW_LIST

#define SIZED_CONTAINER_OR_VIEW_LIST
Value:
"span", "array", "vector", "basic_string_view", "basic_string", \
"initializer_list",

Definition at line 119 of file UnsafeBufferUsage.cpp.

Referenced by isPtrBufferSafe(), and isSafeSpanTwoParamConstruct().

◆ WARNING_GADGET

#define WARNING_GADGET ( name)
Value:
if (name##Gadget::matches(S, Ctx, Result) && \
notInSafeBufferOptOut(*S, &Handler)) { \
WarningGadgets.push_back(std::make_unique<name##Gadget>(Result)); \
return true; \
}
static bool notInSafeBufferOptOut(const Stmt &Node, const UnsafeBufferUsageHandler *Handler)

◆ WARNING_OPTIONAL_GADGET

#define WARNING_OPTIONAL_GADGET ( name)
Value:
if (name##Gadget::matches(S, Ctx, &Handler, Result) && \
notInSafeBufferOptOut(*S, &Handler)) { \
WarningGadgets.push_back(std::make_unique<name##Gadget>(Result)); \
return true; \
}

Function Documentation

◆ applyGadgets()

◆ areEqualIntegers()

◆ areEqualIntegralBinaryOperators()

bool areEqualIntegralBinaryOperators ( const BinaryOperator * E1,
const Expr * E2_LHS,
BinaryOperatorKind BOP,
const Expr * E2_RHS,
ASTContext & Ctx )
static

◆ createDataFixit()

std::optional< FixItList > createDataFixit ( const ASTContext & Ctx,
const DeclRefExpr * DRE )
inlinestatic
Returns
fixit that adds .data() call after \DRE.

Definition at line 3083 of file UnsafeBufferUsage.cpp.

References clang::FixItHint::CreateInsertion(), clang::ASTContext::getLangOpts(), clang::getPastLoc(), clang::ASTContext::getSourceManager(), and SM.

◆ createFunctionOverloadsForParms()

FixItList createFunctionOverloadsForParms ( std::map< const VarDecl *, FixItList > & FixItsForVariable,
const VariableGroupsManager & VarGrpMgr,
const FunctionDecl * FD,
const FixitStrategy & S,
ASTContext & Ctx,
UnsafeBufferUsageHandler & Handler )
static

◆ createOverloadsForFixedParams()

◆ createSpanTypeForVarDecl()

std::optional< std::string > createSpanTypeForVarDecl ( const VarDecl * VD,
const ASTContext & Ctx )
static

◆ eraseVarsForUnfixableGroupMates()

void eraseVarsForUnfixableGroupMates ( std::map< const VarDecl *, FixItList > & FixItsForVariable,
const VariableGroupsManager & VarGrpMgr )
static

Definition at line 3865 of file UnsafeBufferUsage.cpp.

References clang::VariableGroupsManager::getGroupOfVar(), and clang::Member.

Referenced by getFixIts().

◆ findGadgets()

void findGadgets ( const Stmt * S,
ASTContext & Ctx,
const UnsafeBufferUsageHandler & Handler,
bool EmitSuggestions,
FixableGadgetList & FixableGadgets,
WarningGadgetList & WarningGadgets,
DeclUseTracker & Tracker )
static

◆ findStmtsInUnspecifiedLvalueContext()

void findStmtsInUnspecifiedLvalueContext ( const Stmt * S,
const llvm::function_ref< void(const Expr *)> OnResult )
static

◆ findStmtsInUnspecifiedPointerContext()

void findStmtsInUnspecifiedPointerContext ( const Stmt * S,
llvm::function_ref< void(const Stmt *)> InnerMatcher )
static

◆ findStmtsInUnspecifiedUntypedContext()

void findStmtsInUnspecifiedUntypedContext ( const Stmt * S,
llvm::function_ref< void(const Stmt *)> InnerMatcher )
static

Definition at line 383 of file UnsafeBufferUsage.cpp.

Referenced by UUCAddAssignGadget::matches().

◆ fixLocalVarDeclWithSpan()

◆ fixParamWithSpan()

◆ fixUPCAddressofArraySubscriptWithSpan()

◆ fixVarDeclWithArray()

◆ fixVariable()

◆ fixVariableWithArray()

FixItList fixVariableWithArray ( const VarDecl * VD,
const DeclUseTracker & Tracker,
const ASTContext & Ctx,
UnsafeBufferUsageHandler & Handler )
static

Definition at line 3762 of file UnsafeBufferUsage.cpp.

References fixVarDeclWithArray(), and clang::DeclStmt::isSingleDecl().

Referenced by fixVariable().

◆ fixVariableWithSpan()

FixItList fixVariableWithSpan ( const VarDecl * VD,
const DeclUseTracker & Tracker,
ASTContext & Ctx,
UnsafeBufferUsageHandler & Handler )
static

◆ FixVarInitializerWithSpan()

◆ forEachDescendantEvaluatedStmt()

void forEachDescendantEvaluatedStmt ( const Stmt * S,
ASTContext & Ctx,
const UnsafeBufferUsageHandler & Handler,
FastMatcher & Matcher )
static

◆ forEachDescendantStmt()

void forEachDescendantStmt ( const Stmt * S,
ASTContext & Ctx,
const UnsafeBufferUsageHandler & Handler,
FastMatcher & Matcher )
static

◆ getEndCharLoc()

template<typename NodeTy>
std::optional< SourceLocation > getEndCharLoc ( const NodeTy * Node,
const SourceManager & SM,
const LangOptions & LangOpts )
static

◆ getEndOfLine()

StringRef getEndOfLine ( )
static

Definition at line 2892 of file UnsafeBufferUsage.cpp.

Referenced by createOverloadsForFixedParams().

◆ getFixIts()

◆ getFunNameText()

◆ getNaiveStrategy()

template<typename VarDeclIterTy>
FixitStrategy getNaiveStrategy ( llvm::iterator_range< VarDeclIterTy > UnsafeVars)
static

◆ getSourceRangeToTokenEnd()

SourceRange getSourceRangeToTokenEnd ( const Decl * D,
const SourceManager & SM,
const LangOptions & LangOpts )
static

◆ getSpanTypeText()

std::string getSpanTypeText ( StringRef EltTyText,
std::optional< Qualifiers > Quals = std::nullopt )
static

Definition at line 2980 of file UnsafeBufferUsage.cpp.

Referenced by createOverloadsForFixedParams(), and fixParamWithSpan().

◆ getUserFillPlaceHolder()

std::string getUserFillPlaceHolder ( StringRef HintTextToUser = "placeholder")
static

Definition at line 2899 of file UnsafeBufferUsage.cpp.

References s.

Referenced by createOverloadsForFixedParams(), and fixVariableWithSpan().

◆ groupFixablesByVar()

FixableGadgetSets groupFixablesByVar ( FixableGadgetList && AllFixableOperations)
static

Definition at line 2711 of file UnsafeBufferUsage.cpp.

References FixableGadgetSets::byVar, and clang::DeclRefExpr::getDecl().

Referenced by applyGadgets().

◆ groupWarningGadgetsByVar()

WarningGadgetSets groupWarningGadgetsByVar ( const WarningGadgetList & AllUnsafeOperations)
static

◆ hasArrayType()

bool hasArrayType ( const Expr & E)
static

◆ hasConflictingOverload()

◆ hasPointerType()

◆ hasUnsupportedSpecifiers()

◆ ignoreUnsafeBufferInContainer()

bool ignoreUnsafeBufferInContainer ( const Stmt & Node,
const UnsafeBufferUsageHandler * Handler )
static

◆ ignoreUnsafeLibcCall()

bool ignoreUnsafeLibcCall ( const ASTContext & Ctx,
const Stmt & Node,
const UnsafeBufferUsageHandler * Handler )
static

◆ isNonNegativeIntegerExpr()

bool isNonNegativeIntegerExpr ( const Expr * Expr,
const VarDecl * VD,
const ASTContext & Ctx )
static

◆ isParameterOf()

bool isParameterOf ( const VarDecl * VD,
const Decl * D )
static

Definition at line 3857 of file UnsafeBufferUsage.cpp.

References clang::Decl::getDeclContext(), and clang::isa().

Referenced by applyGadgets().

◆ isPtrBufferSafe()

◆ isSafeArraySubscript()

◆ isSafeSpanTwoParamConstruct()

◆ notInSafeBufferOptOut()

bool notInSafeBufferOptOut ( const Stmt & Node,
const UnsafeBufferUsageHandler * Handler )
static

◆ overlapWithMacro()

bool overlapWithMacro ( const FixItList & FixIts)
static

Definition at line 3844 of file UnsafeBufferUsage.cpp.

References clang::FixItHint::RemoveRange.

Referenced by getFixIts().