File indexing completed on 2026-05-10 08:36:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H
0015 #define LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H
0016
0017 #include "clang/AST/Decl.h"
0018 #include "clang/AST/Expr.h"
0019 #include "clang/AST/Stmt.h"
0020 #include "clang/Basic/SourceLocation.h"
0021 #include "llvm/Support/Debug.h"
0022
0023 namespace clang {
0024
0025 using VarGrpTy = std::vector<const VarDecl *>;
0026 using VarGrpRef = ArrayRef<const VarDecl *>;
0027
0028 class VariableGroupsManager {
0029 public:
0030 VariableGroupsManager() = default;
0031 virtual ~VariableGroupsManager() = default;
0032
0033
0034
0035
0036
0037
0038 virtual VarGrpRef getGroupOfVar(const VarDecl *Var,
0039 bool *HasParm = nullptr) const =0;
0040
0041
0042
0043 virtual VarGrpRef getGroupOfParms() const =0;
0044 };
0045
0046
0047
0048
0049
0050 class FixitStrategy {
0051 public:
0052 enum class Kind {
0053 Wontfix,
0054 Span,
0055 Iterator,
0056 Array,
0057 Vector
0058 };
0059
0060 private:
0061 using MapTy = llvm::DenseMap<const VarDecl *, Kind>;
0062
0063 MapTy Map;
0064
0065 public:
0066 FixitStrategy() = default;
0067 FixitStrategy(const FixitStrategy &) = delete;
0068 FixitStrategy &operator=(const FixitStrategy &) = delete;
0069 FixitStrategy(FixitStrategy &&) = default;
0070 FixitStrategy &operator=(FixitStrategy &&) = default;
0071
0072 void set(const VarDecl *VD, Kind K) { Map[VD] = K; }
0073
0074 Kind lookup(const VarDecl *VD) const {
0075 auto I = Map.find(VD);
0076 if (I == Map.end())
0077 return Kind::Wontfix;
0078
0079 return I->second;
0080 }
0081 };
0082
0083
0084
0085 class UnsafeBufferUsageHandler {
0086 #ifndef NDEBUG
0087 public:
0088
0089
0090
0091
0092 using DebugNote = std::pair<SourceLocation, std::string>;
0093 using DebugNoteList = std::vector<DebugNote>;
0094 using DebugNoteByVar = std::map<const VarDecl *, DebugNoteList>;
0095 DebugNoteByVar DebugNotesByVar;
0096 #endif
0097
0098 public:
0099 UnsafeBufferUsageHandler() = default;
0100 virtual ~UnsafeBufferUsageHandler() = default;
0101
0102
0103
0104 using FixItList = llvm::SmallVectorImpl<FixItHint>;
0105
0106
0107 virtual void handleUnsafeOperation(const Stmt *Operation,
0108 bool IsRelatedToDecl, ASTContext &Ctx) = 0;
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120 virtual void handleUnsafeLibcCall(const CallExpr *Call, unsigned PrintfInfo,
0121 ASTContext &Ctx,
0122 const Expr *UnsafeArg = nullptr) = 0;
0123
0124
0125 virtual void handleUnsafeOperationInContainer(const Stmt *Operation,
0126 bool IsRelatedToDecl,
0127 ASTContext &Ctx) = 0;
0128
0129
0130
0131
0132
0133
0134
0135 virtual void
0136 handleUnsafeVariableGroup(const VarDecl *Variable,
0137 const VariableGroupsManager &VarGrpMgr,
0138 FixItList &&Fixes, const Decl *D,
0139 const FixitStrategy &VarTargetTypes) = 0;
0140
0141 #ifndef NDEBUG
0142 public:
0143 bool areDebugNotesRequested() {
0144 DEBUG_WITH_TYPE("SafeBuffers", return true);
0145 return false;
0146 }
0147
0148 void addDebugNoteForVar(const VarDecl *VD, SourceLocation Loc,
0149 std::string Text) {
0150 if (areDebugNotesRequested())
0151 DebugNotesByVar[VD].push_back(std::make_pair(Loc, Text));
0152 }
0153
0154 void clearDebugNotes() {
0155 if (areDebugNotesRequested())
0156 DebugNotesByVar.clear();
0157 }
0158 #endif
0159
0160 public:
0161
0162 virtual bool isSafeBufferOptOut(const SourceLocation &Loc) const = 0;
0163
0164
0165
0166 virtual bool
0167 ignoreUnsafeBufferInContainer(const SourceLocation &Loc) const = 0;
0168
0169
0170 virtual bool
0171 ignoreUnsafeBufferInLibcCall(const SourceLocation &Loc) const = 0;
0172
0173 virtual std::string
0174 getUnsafeBufferUsageAttributeTextAt(SourceLocation Loc,
0175 StringRef WSSuffix = "") const = 0;
0176 };
0177
0178
0179
0180 void checkUnsafeBufferUsage(const Decl *D, UnsafeBufferUsageHandler &Handler,
0181 bool EmitSuggestions);
0182
0183 namespace internal {
0184
0185
0186 bool anyConflict(const llvm::SmallVectorImpl<FixItHint> &FixIts,
0187 const SourceManager &SM);
0188 }
0189 }
0190
0191 #endif