samestep updated this revision to Diff 440702. samestep added a comment. Herald added a project: clang.
- Merge branch 'diagnose-api' into optional-check-diagnose - Use the updated API 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 clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h Index: clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h =================================================================== --- clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -113,10 +113,21 @@ template <typename AnalysisT> llvm::Expected<std::vector< llvm::Optional<DataflowAnalysisState<typename AnalysisT::Lattice>>>> -runDataflowAnalysis(const ControlFlowContext &CFCtx, AnalysisT &Analysis, - const Environment &InitEnv) { - auto TypeErasedBlockStates = - runTypeErasedDataflowAnalysis(CFCtx, Analysis, InitEnv); +runDataflowAnalysis( + const ControlFlowContext &CFCtx, AnalysisT &Analysis, + const Environment &InitEnv, + std::function<void(const Stmt *, const DataflowAnalysisState< + typename AnalysisT::Lattice> &)> + PostVisitStmt = nullptr) { + auto TypeErasedBlockStates = runTypeErasedDataflowAnalysis( + CFCtx, Analysis, InitEnv, + [&PostVisitStmt](const Stmt *Stmt, + const TypeErasedDataflowAnalysisState &State) { + auto *Lattice = + llvm::any_cast<typename AnalysisT::Lattice>(&State.Lattice.Value); + PostVisitStmt(Stmt, DataflowAnalysisState<typename AnalysisT::Lattice>{ + *Lattice, State.Env}); + }); if (!TypeErasedBlockStates) return TypeErasedBlockStates.takeError(); 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 @@ -32,12 +32,13 @@ 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<std::vector<SourceLocation>> analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx) { using dataflow::ControlFlowContext; using dataflow::DataflowAnalysisState; @@ -52,23 +53,23 @@ std::make_unique<dataflow::WatchedLiteralsSolver>()); dataflow::Environment Env(AnalysisContext, FuncDecl); UncheckedOptionalAccessModel Analysis(ASTCtx); + UncheckedOptionalAccessDiagnosis Diagnosis(ASTCtx); + std::vector<SourceLocation> Diagnostics; Expected<std::vector<Optional<DataflowAnalysisState<SourceLocationsLattice>>>> - BlockToOutputState = - dataflow::runDataflowAnalysis(*Context, Analysis, Env); + BlockToOutputState = dataflow::runDataflowAnalysis( + *Context, Analysis, Env, + [&Diagnosis, + &Diagnostics](const Stmt *Stmt, + const DataflowAnalysisState<SourceLocationsLattice> + &State) mutable { + auto StmtDiagnostics = Diagnosis.diagnose(Stmt, State.Env); + std::move(StmtDiagnostics.begin(), StmtDiagnostics.end(), + std::back_inserter(Diagnostics)); + }); 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; - - return std::move(ExitBlockState->Lattice); + return Diagnostics; } void UncheckedOptionalAccessCheck::registerMatchers(MatchFinder *Finder) { @@ -97,9 +98,9 @@ if (FuncDecl->isTemplated()) return; - if (Optional<SourceLocationsLattice> Errors = + if (Optional<std::vector<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/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h =================================================================== --- clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h +++ clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h @@ -113,10 +113,21 @@ template <typename AnalysisT> llvm::Expected<std::vector< llvm::Optional<DataflowAnalysisState<typename AnalysisT::Lattice>>>> -runDataflowAnalysis(const ControlFlowContext &CFCtx, AnalysisT &Analysis, - const Environment &InitEnv) { - auto TypeErasedBlockStates = - runTypeErasedDataflowAnalysis(CFCtx, Analysis, InitEnv); +runDataflowAnalysis( + const ControlFlowContext &CFCtx, AnalysisT &Analysis, + const Environment &InitEnv, + std::function<void(const Stmt *, const DataflowAnalysisState< + typename AnalysisT::Lattice> &)> + PostVisitStmt = nullptr) { + auto TypeErasedBlockStates = runTypeErasedDataflowAnalysis( + CFCtx, Analysis, InitEnv, + [&PostVisitStmt](const Stmt *Stmt, + const TypeErasedDataflowAnalysisState &State) { + auto *Lattice = + llvm::any_cast<typename AnalysisT::Lattice>(&State.Lattice.Value); + PostVisitStmt(Stmt, DataflowAnalysisState<typename AnalysisT::Lattice>{ + *Lattice, State.Env}); + }); if (!TypeErasedBlockStates) return TypeErasedBlockStates.takeError(); 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 @@ -32,12 +32,13 @@ 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<std::vector<SourceLocation>> analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx) { using dataflow::ControlFlowContext; using dataflow::DataflowAnalysisState; @@ -52,23 +53,23 @@ std::make_unique<dataflow::WatchedLiteralsSolver>()); dataflow::Environment Env(AnalysisContext, FuncDecl); UncheckedOptionalAccessModel Analysis(ASTCtx); + UncheckedOptionalAccessDiagnosis Diagnosis(ASTCtx); + std::vector<SourceLocation> Diagnostics; Expected<std::vector<Optional<DataflowAnalysisState<SourceLocationsLattice>>>> - BlockToOutputState = - dataflow::runDataflowAnalysis(*Context, Analysis, Env); + BlockToOutputState = dataflow::runDataflowAnalysis( + *Context, Analysis, Env, + [&Diagnosis, + &Diagnostics](const Stmt *Stmt, + const DataflowAnalysisState<SourceLocationsLattice> + &State) mutable { + auto StmtDiagnostics = Diagnosis.diagnose(Stmt, State.Env); + std::move(StmtDiagnostics.begin(), StmtDiagnostics.end(), + std::back_inserter(Diagnostics)); + }); 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; - - return std::move(ExitBlockState->Lattice); + return Diagnostics; } void UncheckedOptionalAccessCheck::registerMatchers(MatchFinder *Finder) { @@ -97,9 +98,9 @@ if (FuncDecl->isTemplated()) return; - if (Optional<SourceLocationsLattice> Errors = + if (Optional<std::vector<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