mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-21 18:56:49 +00:00
[-Wunsafe-buffer-usage] Add findUnsafePointers (#135421)
This commit is contained in:
parent
d1fd97737e
commit
ee801cdd6e
clang
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user