0
0
mirror of https://github.com/llvm/llvm-project.git synced 2025-04-21 18:56:49 +00:00

[-Wunsafe-buffer-usage] Add findUnsafePointers ()

This commit is contained in:
Jan Korous 2025-04-11 13:28:18 -07:00 committed by GitHub
parent d1fd97737e
commit ee801cdd6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 78 additions and 0 deletions
clang
include/clang/Analysis/Analyses
lib/Analysis

@ -19,6 +19,7 @@
#include "clang/AST/Stmt.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/Support/Debug.h"
#include <set>
namespace clang {
@ -186,6 +187,8 @@ namespace internal {
bool anyConflict(const llvm::SmallVectorImpl<FixItHint> &FixIts,
const SourceManager &SM);
} // namespace internal
std::set<const Expr *> findUnsafePointers(const FunctionDecl *FD);
} // end namespace clang
#endif /* LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H */

@ -1163,6 +1163,8 @@ public:
virtual void handleUnsafeOperation(UnsafeBufferUsageHandler &Handler,
bool IsRelatedToDecl,
ASTContext &Ctx) const = 0;
virtual SmallVector<const Expr *, 1> getUnsafePtrs() const = 0;
};
/// Fixable gadgets correspond to code patterns that aren't always unsafe but
@ -1245,6 +1247,10 @@ public:
return std::move(Uses);
}
SmallVector<const Expr *, 1> getUnsafePtrs() const override {
return {Op->getSubExpr()->IgnoreParenImpCasts()};
}
};
/// A decrement of a pointer-type value is unsafe as it may run the pointer
@ -1288,6 +1294,10 @@ public:
return {};
}
SmallVector<const Expr *, 1> getUnsafePtrs() const override {
return {Op->getSubExpr()->IgnoreParenImpCasts()};
}
};
/// Array subscript expressions on raw pointers as if they're arrays. Unsafe as
@ -1337,6 +1347,10 @@ public:
return {};
}
SmallVector<const Expr *, 1> getUnsafePtrs() const override {
return {ASE->getBase()->IgnoreParenImpCasts()};
}
};
/// A pointer arithmetic expression of one of the forms:
@ -1400,6 +1414,11 @@ public:
return {};
}
SmallVector<const Expr *, 1> getUnsafePtrs() const override {
return {Ptr->IgnoreParenImpCasts()};
}
// FIXME: pointer adding zero should be fine
// FIXME: this gadge will need a fix-it
};
@ -1457,6 +1476,8 @@ public:
}
return {};
}
SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
};
/// A pointer initialization expression of the form:
@ -1689,6 +1710,8 @@ public:
SourceLocation getSourceLoc() const override { return Op->getBeginLoc(); }
DeclUseList getClaimedVarUseSites() const override { return {}; }
SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
};
/// A call of a constructor that performs unchecked buffer operations
@ -1727,6 +1750,8 @@ public:
SourceLocation getSourceLoc() const override { return Op->getBeginLoc(); }
DeclUseList getClaimedVarUseSites() const override { return {}; }
SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
};
// Warning gadget for unsafe invocation of span::data method.
@ -1793,6 +1818,8 @@ private:
return true;
return false;
}
SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
};
class UnsafeLibcFunctionCallGadget : public WarningGadget {
@ -1896,6 +1923,8 @@ public:
}
DeclUseList getClaimedVarUseSites() const override { return {}; }
SmallVector<const Expr *, 1> getUnsafePtrs() const override { return {}; }
};
// Represents expressions of the form `DRE[*]` in the Unspecified Lvalue
@ -2467,6 +2496,52 @@ template <typename NodeTy> struct CompareNode {
}
};
std::set<const Expr *> clang::findUnsafePointers(const FunctionDecl *FD) {
class MockReporter : public UnsafeBufferUsageHandler {
public:
MockReporter() {}
void handleUnsafeOperation(const Stmt *, bool, ASTContext &) override {}
void handleUnsafeLibcCall(const CallExpr *, unsigned, ASTContext &,
const Expr *UnsafeArg = nullptr) override {}
void handleUnsafeOperationInContainer(const Stmt *, bool,
ASTContext &) override {}
void handleUnsafeVariableGroup(const VarDecl *,
const VariableGroupsManager &, FixItList &&,
const Decl *,
const FixitStrategy &) override {}
bool isSafeBufferOptOut(const SourceLocation &) const override {
return false;
}
bool ignoreUnsafeBufferInContainer(const SourceLocation &) const override {
return false;
}
bool ignoreUnsafeBufferInLibcCall(const SourceLocation &) const override {
return false;
}
std::string getUnsafeBufferUsageAttributeTextAt(
SourceLocation, StringRef WSSuffix = "") const override {
return "";
}
};
FixableGadgetList FixableGadgets;
WarningGadgetList WarningGadgets;
DeclUseTracker Tracker;
MockReporter IgnoreHandler;
findGadgets(FD->getBody(), FD->getASTContext(), IgnoreHandler, false,
FixableGadgets, WarningGadgets, Tracker);
std::set<const Expr *> Result;
for (auto &G : WarningGadgets) {
for (const Expr *E : G->getUnsafePtrs()) {
Result.insert(E);
}
}
return Result;
}
struct WarningGadgetSets {
std::map<const VarDecl *, std::set<const WarningGadget *>,
// To keep keys sorted by their locations in the map so that the