From 246626a8cfd3d4f910baadeff4d5aa544b9d4550 Mon Sep 17 00:00:00 2001 From: Martin Braenne Date: Tue, 23 May 2023 07:32:10 +0000 Subject: [PATCH] [clang][dataflow] Add a `ControlFlowContext::build()` overload taking a `FunctionDecl`. This is the most common use case, so it makes sense to have a specific overload for it. Reviewed By: xazax.hun Differential Revision: https://reviews.llvm.org/D151183 --- .../clang/Analysis/FlowSensitive/ControlFlowContext.h | 5 +++++ .../lib/Analysis/FlowSensitive/ControlFlowContext.cpp | 10 ++++++++++ .../Analysis/FlowSensitive/DataflowAnalysisContext.cpp | 4 ++-- .../unittests/Analysis/FlowSensitive/TestingSupport.h | 3 +-- .../FlowSensitive/TypeErasedDataflowAnalysisTest.cpp | 4 ++-- 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h b/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h index b51e2cb23634d..f327011766069 100644 --- a/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h +++ b/clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h @@ -31,6 +31,11 @@ namespace dataflow { /// analysis. class ControlFlowContext { public: + /// Builds a ControlFlowContext from a `FunctionDecl`. + /// `Func.hasBody()` must be true, and `Func.isTemplated()` must be false. + static llvm::Expected build(const FunctionDecl &Func, + ASTContext &C); + /// Builds a ControlFlowContext from an AST node. `D` is the function in which /// `S` resides. `D.isTemplated()` must be false. static llvm::Expected build(const Decl &D, Stmt &S, diff --git a/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp b/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp index 4556787d10a8e..c62bff33524cf 100644 --- a/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp @@ -67,6 +67,16 @@ static llvm::BitVector findReachableBlocks(const CFG &Cfg) { return BlockReachable; } +llvm::Expected +ControlFlowContext::build(const FunctionDecl &Func, ASTContext &C) { + if (!Func.hasBody()) + return llvm::createStringError( + std::make_error_code(std::errc::invalid_argument), + "Cannot analyze function without a body"); + + return build(Func, *Func.getBody(), C); +} + llvm::Expected ControlFlowContext::build(const Decl &D, Stmt &S, ASTContext &C) { if (D.isTemplated()) diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp index 73428ac250ad3..32612397ec024 100644 --- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp +++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp @@ -210,8 +210,8 @@ DataflowAnalysisContext::getControlFlowContext(const FunctionDecl *F) { if (It != FunctionContexts.end()) return &It->second; - if (Stmt *Body = F->getBody()) { - auto CFCtx = ControlFlowContext::build(*F, *Body, F->getASTContext()); + if (F->hasBody()) { + auto CFCtx = ControlFlowContext::build(*F, F->getASTContext()); // FIXME: Handle errors. assert(CFCtx); auto Result = FunctionContexts.insert({F, std::move(*CFCtx)}); diff --git a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h index ff7d27d6540cc..d5591bee12dc2 100644 --- a/clang/unittests/Analysis/FlowSensitive/TestingSupport.h +++ b/clang/unittests/Analysis/FlowSensitive/TestingSupport.h @@ -241,8 +241,7 @@ checkDataflow(AnalysisInputs AI, llvm::errc::invalid_argument, "Could not find the target function."); // Build the control flow graph for the target function. - auto MaybeCFCtx = - ControlFlowContext::build(*Target, *Target->getBody(), Context); + auto MaybeCFCtx = ControlFlowContext::build(*Target, Context); if (!MaybeCFCtx) return MaybeCFCtx.takeError(); auto &CFCtx = *MaybeCFCtx; diff --git a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp index 5bfb9e53778b0..84b10c87f6b19 100644 --- a/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp @@ -67,8 +67,8 @@ runAnalysis(llvm::StringRef Code, AnalysisT (*MakeAnalysis)(ASTContext &)) { Stmt *Body = Func->getBody(); assert(Body != nullptr); - auto CFCtx = llvm::cantFail( - ControlFlowContext::build(*Func, *Body, AST->getASTContext())); + auto CFCtx = + llvm::cantFail(ControlFlowContext::build(*Func, AST->getASTContext())); AnalysisT Analysis = MakeAnalysis(AST->getASTContext()); DataflowAnalysisContext DACtx(std::make_unique());