samestep updated this revision to Diff 439373. samestep added a comment. - Merge branch 'diagnose-api' into optional-check-diagnose
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D128352/new/ https://reviews.llvm.org/D128352 Files: clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp Index: clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp +++ clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp @@ -17,11 +17,12 @@ #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/DataflowLattice.h" +#include "clang/Analysis/FlowSensitive/Diagnosis.h" #include "clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h" -#include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h" #include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/Any.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Error.h" #include <memory> @@ -31,16 +32,16 @@ namespace tidy { namespace bugprone { using ast_matchers::MatchFinder; -using dataflow::SourceLocationsLattice; +using dataflow::UncheckedOptionalAccessDiagnosis; using dataflow::UncheckedOptionalAccessModel; using llvm::Optional; static constexpr llvm::StringLiteral FuncID("fun"); -static Optional<SourceLocationsLattice> +static Optional<llvm::DenseSet<SourceLocation>> analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx) { using dataflow::ControlFlowContext; - using dataflow::DataflowAnalysisState; + using dataflow::TypeErasedDataflowAnalysisState; using llvm::Expected; Expected<ControlFlowContext> Context = @@ -52,23 +53,23 @@ std::make_unique<dataflow::WatchedLiteralsSolver>()); dataflow::Environment Env(AnalysisContext, FuncDecl); UncheckedOptionalAccessModel Analysis(ASTCtx); - Expected<std::vector<Optional<DataflowAnalysisState<SourceLocationsLattice>>>> + Expected<std::vector<Optional<TypeErasedDataflowAnalysisState>>> BlockToOutputState = - dataflow::runDataflowAnalysis(*Context, Analysis, Env); + dataflow::runTypeErasedDataflowAnalysis(*Context, Analysis, Env); if (!BlockToOutputState) return llvm::None; - assert(Context->getCFG().getExit().getBlockID() < BlockToOutputState->size()); - const Optional<DataflowAnalysisState<SourceLocationsLattice>> - &ExitBlockState = - (*BlockToOutputState)[Context->getCFG().getExit().getBlockID()]; - // `runDataflowAnalysis` doesn't guarantee that the exit block is visited; - // for example, when it is unreachable. - // FIXME: Diagnose violations even when the exit block is unreachable. - if (!ExitBlockState) - return llvm::None; + UncheckedOptionalAccessDiagnosis Diagnosis(ASTCtx); + dataflow::Diagnosis<UncheckedOptionalAccessModel::Lattice, + llvm::DenseSet<SourceLocation>> + Diagnose = [&Diagnosis](const Stmt *Stmt, + const UncheckedOptionalAccessModel::Lattice &, + const dataflow::Environment &Env) { + return Diagnosis.diagnose(Stmt, Env); + }; - return std::move(ExitBlockState->Lattice); + return dataflow::diagnoseCFG(*Context, *BlockToOutputState, Env, Analysis, + std::move(Diagnose)); } void UncheckedOptionalAccessCheck::registerMatchers(MatchFinder *Finder) { @@ -97,9 +98,9 @@ if (FuncDecl->isTemplated()) return; - if (Optional<SourceLocationsLattice> Errors = + if (Optional<llvm::DenseSet<SourceLocation>> Errors = analyzeFunction(*FuncDecl, *Result.Context)) - for (const SourceLocation &Loc : Errors->getSourceLocations()) + for (const SourceLocation &Loc : *Errors) diag(Loc, "unchecked access to optional value"); }
Index: clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp =================================================================== --- clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp +++ clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp @@ -17,11 +17,12 @@ #include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h" #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h" #include "clang/Analysis/FlowSensitive/DataflowLattice.h" +#include "clang/Analysis/FlowSensitive/Diagnosis.h" #include "clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h" -#include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h" #include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/Any.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Error.h" #include <memory> @@ -31,16 +32,16 @@ namespace tidy { namespace bugprone { using ast_matchers::MatchFinder; -using dataflow::SourceLocationsLattice; +using dataflow::UncheckedOptionalAccessDiagnosis; using dataflow::UncheckedOptionalAccessModel; using llvm::Optional; static constexpr llvm::StringLiteral FuncID("fun"); -static Optional<SourceLocationsLattice> +static Optional<llvm::DenseSet<SourceLocation>> analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx) { using dataflow::ControlFlowContext; - using dataflow::DataflowAnalysisState; + using dataflow::TypeErasedDataflowAnalysisState; using llvm::Expected; Expected<ControlFlowContext> Context = @@ -52,23 +53,23 @@ std::make_unique<dataflow::WatchedLiteralsSolver>()); dataflow::Environment Env(AnalysisContext, FuncDecl); UncheckedOptionalAccessModel Analysis(ASTCtx); - Expected<std::vector<Optional<DataflowAnalysisState<SourceLocationsLattice>>>> + Expected<std::vector<Optional<TypeErasedDataflowAnalysisState>>> BlockToOutputState = - dataflow::runDataflowAnalysis(*Context, Analysis, Env); + dataflow::runTypeErasedDataflowAnalysis(*Context, Analysis, Env); if (!BlockToOutputState) return llvm::None; - assert(Context->getCFG().getExit().getBlockID() < BlockToOutputState->size()); - const Optional<DataflowAnalysisState<SourceLocationsLattice>> - &ExitBlockState = - (*BlockToOutputState)[Context->getCFG().getExit().getBlockID()]; - // `runDataflowAnalysis` doesn't guarantee that the exit block is visited; - // for example, when it is unreachable. - // FIXME: Diagnose violations even when the exit block is unreachable. - if (!ExitBlockState) - return llvm::None; + UncheckedOptionalAccessDiagnosis Diagnosis(ASTCtx); + dataflow::Diagnosis<UncheckedOptionalAccessModel::Lattice, + llvm::DenseSet<SourceLocation>> + Diagnose = [&Diagnosis](const Stmt *Stmt, + const UncheckedOptionalAccessModel::Lattice &, + const dataflow::Environment &Env) { + return Diagnosis.diagnose(Stmt, Env); + }; - return std::move(ExitBlockState->Lattice); + return dataflow::diagnoseCFG(*Context, *BlockToOutputState, Env, Analysis, + std::move(Diagnose)); } void UncheckedOptionalAccessCheck::registerMatchers(MatchFinder *Finder) { @@ -97,9 +98,9 @@ if (FuncDecl->isTemplated()) return; - if (Optional<SourceLocationsLattice> Errors = + if (Optional<llvm::DenseSet<SourceLocation>> Errors = analyzeFunction(*FuncDecl, *Result.Context)) - for (const SourceLocation &Loc : Errors->getSourceLocations()) + for (const SourceLocation &Loc : *Errors) diag(Loc, "unchecked access to optional value"); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits