[clang][dataflow] Change diagnoseFunction to use llvm::SmallVector instead of std::vector. (#66014)
The template is agnostic as to the type used by the list, as long as it is compatible with `llvm::move` and `std::back_inserter`. In practice, we've encountered analyses which use different types (`llvm::SmallVector` vs `std::vector`), so it seems preferable to leave this open to the caller.
This commit is contained in:
committed by
GitHub
parent
bf85f27370
commit
004a7cea70
@@ -13,10 +13,8 @@
|
||||
#include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
|
||||
#include "clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace clang::tidy::bugprone {
|
||||
using ast_matchers::MatchFinder;
|
||||
@@ -54,7 +52,7 @@ void UncheckedOptionalAccessCheck::check(
|
||||
UncheckedOptionalAccessDiagnoser Diagnoser(ModelOptions);
|
||||
// FIXME: Allow user to set the (defaulted) SAT iterations max for
|
||||
// `diagnoseFunction` with config options.
|
||||
if (llvm::Expected<std::vector<SourceLocation>> Locs =
|
||||
if (llvm::Expected<llvm::SmallVector<SourceLocation>> Locs =
|
||||
dataflow::diagnoseFunction<UncheckedOptionalAccessModel,
|
||||
SourceLocation>(*FuncDecl, *Result.Context,
|
||||
Diagnoser))
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "llvm/ADT/Any.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/STLFunctionalExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/Errc.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
@@ -246,9 +247,9 @@ runDataflowAnalysis(
|
||||
/// - This limit is still low enough to keep runtimes acceptable (on typical
|
||||
/// machines) in cases where we hit the limit.
|
||||
template <typename AnalysisT, typename Diagnostic>
|
||||
llvm::Expected<std::vector<Diagnostic>> diagnoseFunction(
|
||||
llvm::Expected<llvm::SmallVector<Diagnostic>> diagnoseFunction(
|
||||
const FunctionDecl &FuncDecl, ASTContext &ASTCtx,
|
||||
llvm::function_ref<std::vector<Diagnostic>(
|
||||
llvm::function_ref<llvm::SmallVector<Diagnostic>(
|
||||
const CFGElement &, ASTContext &,
|
||||
const TransferStateForDiagnostics<typename AnalysisT::Lattice> &)>
|
||||
Diagnoser,
|
||||
@@ -263,7 +264,7 @@ llvm::Expected<std::vector<Diagnostic>> diagnoseFunction(
|
||||
DataflowAnalysisContext AnalysisContext(std::move(OwnedSolver));
|
||||
Environment Env(AnalysisContext, FuncDecl);
|
||||
AnalysisT Analysis(ASTCtx);
|
||||
std::vector<Diagnostic> Diagnostics;
|
||||
llvm::SmallVector<Diagnostic> Diagnostics;
|
||||
if (llvm::Error Err =
|
||||
runTypeErasedDataflowAnalysis(
|
||||
*Context, Analysis, Env,
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
|
||||
#include "clang/Analysis/FlowSensitive/NoopLattice.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include <vector>
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace clang {
|
||||
namespace dataflow {
|
||||
@@ -74,14 +74,14 @@ public:
|
||||
UncheckedOptionalAccessDiagnoser(
|
||||
UncheckedOptionalAccessModelOptions Options = {});
|
||||
|
||||
std::vector<SourceLocation>
|
||||
llvm::SmallVector<SourceLocation>
|
||||
operator()(const CFGElement &Elt, ASTContext &Ctx,
|
||||
const TransferStateForDiagnostics<NoopLattice> &State) {
|
||||
return DiagnoseMatchSwitch(Elt, Ctx, State.Env);
|
||||
}
|
||||
|
||||
private:
|
||||
CFGMatchSwitch<const Environment, std::vector<SourceLocation>>
|
||||
CFGMatchSwitch<const Environment, llvm::SmallVector<SourceLocation>>
|
||||
DiagnoseMatchSwitch;
|
||||
};
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
namespace dataflow {
|
||||
@@ -913,8 +912,8 @@ auto buildTransferMatchSwitch() {
|
||||
.Build();
|
||||
}
|
||||
|
||||
std::vector<SourceLocation> diagnoseUnwrapCall(const Expr *ObjectExpr,
|
||||
const Environment &Env) {
|
||||
llvm::SmallVector<SourceLocation> diagnoseUnwrapCall(const Expr *ObjectExpr,
|
||||
const Environment &Env) {
|
||||
if (auto *OptionalVal = getValueBehindPossiblePointer(*ObjectExpr, Env)) {
|
||||
auto *Prop = OptionalVal->getProperty("has_value");
|
||||
if (auto *HasValueVal = cast_or_null<BoolValue>(Prop)) {
|
||||
@@ -935,7 +934,8 @@ auto buildDiagnoseMatchSwitch(
|
||||
// lot of duplicated work (e.g. string comparisons), consider providing APIs
|
||||
// that avoid it through memoization.
|
||||
auto IgnorableOptional = ignorableOptional(Options);
|
||||
return CFGMatchSwitchBuilder<const Environment, std::vector<SourceLocation>>()
|
||||
return CFGMatchSwitchBuilder<const Environment,
|
||||
llvm::SmallVector<SourceLocation>>()
|
||||
// optional::value
|
||||
.CaseOfCFGStmt<CXXMemberCallExpr>(
|
||||
valueCall(IgnorableOptional),
|
||||
|
||||
@@ -98,7 +98,7 @@ TEST(DataflowAnalysisTest, DiagnoseFunctionDiagnoserCalledOnEachElement) {
|
||||
cast<FunctionDecl>(findValueDecl(AST->getASTContext(), "target"));
|
||||
auto Diagnoser = [](const CFGElement &Elt, ASTContext &,
|
||||
const TransferStateForDiagnostics<NoopLattice> &) {
|
||||
std::vector<std::string> Diagnostics(1);
|
||||
llvm::SmallVector<std::string> Diagnostics(1);
|
||||
llvm::raw_string_ostream OS(Diagnostics.front());
|
||||
Elt.dumpToStream(OS);
|
||||
return Diagnostics;
|
||||
|
||||
Reference in New Issue
Block a user