aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Analysis
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Analysis')
-rw-r--r--clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp (renamed from clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp)21
-rw-r--r--clang/lib/Analysis/FlowSensitive/CMakeLists.txt2
-rw-r--r--clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp10
-rw-r--r--clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp20
-rw-r--r--clang/lib/Analysis/FlowSensitive/Logger.cpp8
-rw-r--r--clang/lib/Analysis/FlowSensitive/Transfer.cpp19
-rw-r--r--clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp40
7 files changed, 58 insertions, 62 deletions
diff --git a/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp
index 7c9f8fb..3813b8c 100644
--- a/clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp
+++ b/clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp
@@ -1,4 +1,4 @@
-//===- ControlFlowContext.cpp ---------------------------------------------===//
+//===- AdornedCFG.cpp ---------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -6,12 +6,12 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines a ControlFlowContext class that is used by dataflow
-// analyses that run over Control-Flow Graphs (CFGs).
+// This file defines an `AdornedCFG` class that is used by dataflow analyses
+// that run over Control-Flow Graphs (CFGs).
//
//===----------------------------------------------------------------------===//
-#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Stmt.h"
@@ -126,8 +126,7 @@ buildContainsExprConsumedInDifferentBlock(
return Result;
}
-llvm::Expected<ControlFlowContext>
-ControlFlowContext::build(const FunctionDecl &Func) {
+llvm::Expected<AdornedCFG> AdornedCFG::build(const FunctionDecl &Func) {
if (!Func.doesThisDeclarationHaveABody())
return llvm::createStringError(
std::make_error_code(std::errc::invalid_argument),
@@ -136,8 +135,8 @@ ControlFlowContext::build(const FunctionDecl &Func) {
return build(Func, *Func.getBody(), Func.getASTContext());
}
-llvm::Expected<ControlFlowContext>
-ControlFlowContext::build(const Decl &D, Stmt &S, ASTContext &C) {
+llvm::Expected<AdornedCFG> AdornedCFG::build(const Decl &D, Stmt &S,
+ ASTContext &C) {
if (D.isTemplated())
return llvm::createStringError(
std::make_error_code(std::errc::invalid_argument),
@@ -175,9 +174,9 @@ ControlFlowContext::build(const Decl &D, Stmt &S, ASTContext &C) {
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock =
buildContainsExprConsumedInDifferentBlock(*Cfg, StmtToBlock);
- return ControlFlowContext(D, std::move(Cfg), std::move(StmtToBlock),
- std::move(BlockReachable),
- std::move(ContainsExprConsumedInDifferentBlock));
+ return AdornedCFG(D, std::move(Cfg), std::move(StmtToBlock),
+ std::move(BlockReachable),
+ std::move(ContainsExprConsumedInDifferentBlock));
}
} // namespace dataflow
diff --git a/clang/lib/Analysis/FlowSensitive/CMakeLists.txt b/clang/lib/Analysis/FlowSensitive/CMakeLists.txt
index 5af4ecf..a3b5d9a 100644
--- a/clang/lib/Analysis/FlowSensitive/CMakeLists.txt
+++ b/clang/lib/Analysis/FlowSensitive/CMakeLists.txt
@@ -1,6 +1,6 @@
add_clang_library(clangAnalysisFlowSensitive
+ AdornedCFG.cpp
Arena.cpp
- ControlFlowContext.cpp
DataflowAnalysisContext.cpp
DataflowEnvironment.cpp
Formula.cpp
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
index f4c4af0..d520539 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
@@ -288,8 +288,8 @@ void DataflowAnalysisContext::dumpFlowCondition(Atom Token,
}
}
-const ControlFlowContext *
-DataflowAnalysisContext::getControlFlowContext(const FunctionDecl *F) {
+const AdornedCFG *
+DataflowAnalysisContext::getAdornedCFG(const FunctionDecl *F) {
// Canonicalize the key:
F = F->getDefinition();
if (F == nullptr)
@@ -299,10 +299,10 @@ DataflowAnalysisContext::getControlFlowContext(const FunctionDecl *F) {
return &It->second;
if (F->doesThisDeclarationHaveABody()) {
- auto CFCtx = ControlFlowContext::build(*F);
+ auto ACFG = AdornedCFG::build(*F);
// FIXME: Handle errors.
- assert(CFCtx);
- auto Result = FunctionContexts.insert({F, std::move(*CFCtx)});
+ assert(ACFG);
+ auto Result = FunctionContexts.insert({F, std::move(*ACFG)});
return &Result.first->second;
}
diff --git a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
index 6afd66d..397a8d8 100644
--- a/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
+++ b/clang/lib/Analysis/FlowSensitive/HTMLLogger.cpp
@@ -54,7 +54,7 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/Analysis/FlowSensitive/DebugSupport.h"
#include "clang/Analysis/FlowSensitive/Logger.h"
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
@@ -162,7 +162,7 @@ class HTMLLogger : public Logger {
llvm::raw_string_ostream JStringStream{JSON};
llvm::json::OStream JOS{JStringStream, /*Indent=*/2};
- const ControlFlowContext *CFC;
+ const AdornedCFG *ACFG;
// Timeline of iterations of CFG block visitation.
std::vector<Iteration> Iters;
// Indexes in `Iters` of the iterations for each block.
@@ -176,15 +176,15 @@ class HTMLLogger : public Logger {
public:
explicit HTMLLogger(StreamFactory Streams) : Streams(std::move(Streams)) {}
- void beginAnalysis(const ControlFlowContext &CFC,
+ void beginAnalysis(const AdornedCFG &ACFG,
TypeErasedDataflowAnalysis &A) override {
OS = Streams();
- this->CFC = &CFC;
+ this->ACFG = &ACFG;
*OS << llvm::StringRef(HTMLLogger_html).split("<?INJECT?>").first;
- BlockConverged.resize(CFC.getCFG().getNumBlockIDs());
+ BlockConverged.resize(ACFG.getCFG().getNumBlockIDs());
- const auto &D = CFC.getDecl();
+ const auto &D = ACFG.getDecl();
const auto &SM = A.getASTContext().getSourceManager();
*OS << "<title>";
if (const auto *ND = dyn_cast<NamedDecl>(&D))
@@ -345,7 +345,7 @@ private:
// tokens are associated with, and even which BB element (so that clicking
// can select the right element).
void writeCode() {
- const auto &AST = CFC->getDecl().getASTContext();
+ const auto &AST = ACFG->getDecl().getASTContext();
bool Invalid = false;
// Extract the source code from the original file.
@@ -353,7 +353,7 @@ private:
// indentation to worry about), but we need the boundaries of particular
// AST nodes and the printer doesn't provide this.
auto Range = clang::Lexer::makeFileCharRange(
- CharSourceRange::getTokenRange(CFC->getDecl().getSourceRange()),
+ CharSourceRange::getTokenRange(ACFG->getDecl().getSourceRange()),
AST.getSourceManager(), AST.getLangOpts());
if (Range.isInvalid())
return;
@@ -419,7 +419,7 @@ private:
// Construct one TokenInfo per character in a flat array.
// This is inefficient (chars in a token all have the same info) but simple.
std::vector<TokenInfo> State(Code.size());
- for (const auto *Block : CFC->getCFG()) {
+ for (const auto *Block : ACFG->getCFG()) {
unsigned EltIndex = 0;
for (const auto& Elt : *Block) {
++EltIndex;
@@ -480,7 +480,7 @@ private:
// out to `dot` to turn it into an SVG.
void writeCFG() {
*OS << "<template data-copy='cfg'>\n";
- if (auto SVG = renderSVG(buildCFGDot(CFC->getCFG())))
+ if (auto SVG = renderSVG(buildCFGDot(ACFG->getCFG())))
*OS << *SVG;
else
*OS << "Can't draw CFG: " << toString(SVG.takeError());
diff --git a/clang/lib/Analysis/FlowSensitive/Logger.cpp b/clang/lib/Analysis/FlowSensitive/Logger.cpp
index 8c401df..8f40768 100644
--- a/clang/lib/Analysis/FlowSensitive/Logger.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Logger.cpp
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Analysis/FlowSensitive/Logger.h"
-#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
#include "llvm/Support/WithColor.h"
@@ -33,17 +33,17 @@ struct TextualLogger final : Logger {
TextualLogger(llvm::raw_ostream &OS)
: OS(OS), ShowColors(llvm::WithColor::defaultAutoDetectFunction()(OS)) {}
- virtual void beginAnalysis(const ControlFlowContext &CFG,
+ virtual void beginAnalysis(const AdornedCFG &ACFG,
TypeErasedDataflowAnalysis &Analysis) override {
{
llvm::WithColor Header(OS, llvm::raw_ostream::Colors::RED, /*Bold=*/true);
OS << "=== Beginning data flow analysis ===\n";
}
- auto &D = CFG.getDecl();
+ auto &D = ACFG.getDecl();
D.print(OS);
OS << "\n";
D.dump(OS);
- CurrentCFG = &CFG.getCFG();
+ CurrentCFG = &ACFG.getCFG();
CurrentCFG->print(OS, Analysis.getASTContext().getLangOpts(), ShowColors);
CurrentAnalysis = &Analysis;
}
diff --git a/clang/lib/Analysis/FlowSensitive/Transfer.cpp b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
index 8b44bcb..19d6810 100644
--- a/clang/lib/Analysis/FlowSensitive/Transfer.cpp
+++ b/clang/lib/Analysis/FlowSensitive/Transfer.cpp
@@ -20,7 +20,7 @@
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtVisitor.h"
-#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
+#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
#include "clang/Analysis/FlowSensitive/NoopAnalysis.h"
#include "clang/Analysis/FlowSensitive/RecordOps.h"
@@ -38,9 +38,9 @@ namespace clang {
namespace dataflow {
const Environment *StmtToEnvMap::getEnvironment(const Stmt &S) const {
- auto BlockIt = CFCtx.getStmtToBlock().find(&ignoreCFGOmittedNodes(S));
- assert(BlockIt != CFCtx.getStmtToBlock().end());
- if (!CFCtx.isBlockReachable(*BlockIt->getSecond()))
+ auto BlockIt = ACFG.getStmtToBlock().find(&ignoreCFGOmittedNodes(S));
+ assert(BlockIt != ACFG.getStmtToBlock().end());
+ if (!ACFG.isBlockReachable(*BlockIt->getSecond()))
return nullptr;
if (BlockIt->getSecond()->getBlockID() == CurBlockID)
return &CurState.Env;
@@ -855,27 +855,26 @@ private:
Env.canDescend(Options.ContextSensitiveOpts->Depth, F)))
return;
- const ControlFlowContext *CFCtx =
- Env.getDataflowAnalysisContext().getControlFlowContext(F);
- if (!CFCtx)
+ const AdornedCFG *ACFG = Env.getDataflowAnalysisContext().getAdornedCFG(F);
+ if (!ACFG)
return;
// FIXME: We don't support context-sensitive analysis of recursion, so
// we should return early here if `F` is the same as the `FunctionDecl`
// holding `S` itself.
- auto ExitBlock = CFCtx->getCFG().getExit().getBlockID();
+ auto ExitBlock = ACFG->getCFG().getExit().getBlockID();
auto CalleeEnv = Env.pushCall(S);
// FIXME: Use the same analysis as the caller for the callee. Note,
// though, that doing so would require support for changing the analysis's
// ASTContext.
- auto Analysis = NoopAnalysis(CFCtx->getDecl().getASTContext(),
+ auto Analysis = NoopAnalysis(ACFG->getDecl().getASTContext(),
DataflowAnalysisOptions{Options});
auto BlockToOutputState =
- dataflow::runDataflowAnalysis(*CFCtx, Analysis, CalleeEnv);
+ dataflow::runDataflowAnalysis(*ACFG, Analysis, CalleeEnv);
assert(BlockToOutputState);
assert(ExitBlock < BlockToOutputState->size());
diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
index 939247c..721a11c 100644
--- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
+++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
@@ -150,20 +150,19 @@ private:
/// Holds data structures required for running dataflow analysis.
struct AnalysisContext {
- AnalysisContext(const ControlFlowContext &CFCtx,
- TypeErasedDataflowAnalysis &Analysis,
+ AnalysisContext(const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis,
const Environment &InitEnv,
llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>>
BlockStates)
- : CFCtx(CFCtx), Analysis(Analysis), InitEnv(InitEnv),
+ : ACFG(ACFG), Analysis(Analysis), InitEnv(InitEnv),
Log(*InitEnv.getDataflowAnalysisContext().getOptions().Log),
BlockStates(BlockStates) {
- Log.beginAnalysis(CFCtx, Analysis);
+ Log.beginAnalysis(ACFG, Analysis);
}
~AnalysisContext() { Log.endAnalysis(); }
/// Contains the CFG being analyzed.
- const ControlFlowContext &CFCtx;
+ const AdornedCFG &ACFG;
/// The analysis to be run.
TypeErasedDataflowAnalysis &Analysis;
/// Initial state to start the analysis.
@@ -176,19 +175,19 @@ struct AnalysisContext {
class PrettyStackTraceAnalysis : public llvm::PrettyStackTraceEntry {
public:
- PrettyStackTraceAnalysis(const ControlFlowContext &CFCtx, const char *Message)
- : CFCtx(CFCtx), Message(Message) {}
+ PrettyStackTraceAnalysis(const AdornedCFG &ACFG, const char *Message)
+ : ACFG(ACFG), Message(Message) {}
void print(raw_ostream &OS) const override {
OS << Message << "\n";
OS << "Decl:\n";
- CFCtx.getDecl().dump(OS);
+ ACFG.getDecl().dump(OS);
OS << "CFG:\n";
- CFCtx.getCFG().print(OS, LangOptions(), false);
+ ACFG.getCFG().print(OS, LangOptions(), false);
}
private:
- const ControlFlowContext &CFCtx;
+ const AdornedCFG &ACFG;
const char *Message;
};
@@ -303,7 +302,7 @@ computeBlockInputState(const CFGBlock &Block, AnalysisContext &AC) {
// See `NoreturnDestructorTest` for concrete examples.
if (Block.succ_begin()->getReachableBlock() != nullptr &&
Block.succ_begin()->getReachableBlock()->hasNoReturnElement()) {
- auto &StmtToBlock = AC.CFCtx.getStmtToBlock();
+ auto &StmtToBlock = AC.ACFG.getStmtToBlock();
auto StmtBlock = StmtToBlock.find(Block.getTerminatorStmt());
assert(StmtBlock != StmtToBlock.end());
llvm::erase(Preds, StmtBlock->getSecond());
@@ -319,7 +318,7 @@ computeBlockInputState(const CFGBlock &Block, AnalysisContext &AC) {
// all predecessors have expression state consumed in a different block.
Environment::ExprJoinBehavior JoinBehavior = Environment::DiscardExprState;
for (const CFGBlock *Pred : Preds) {
- if (Pred && AC.CFCtx.containsExprConsumedInDifferentBlock(*Pred)) {
+ if (Pred && AC.ACFG.containsExprConsumedInDifferentBlock(*Pred)) {
JoinBehavior = Environment::KeepExprState;
break;
}
@@ -368,7 +367,7 @@ builtinTransferStatement(unsigned CurBlockID, const CFGStmt &Elt,
AnalysisContext &AC) {
const Stmt *S = Elt.getStmt();
assert(S != nullptr);
- transfer(StmtToEnvMap(AC.CFCtx, AC.BlockStates, CurBlockID, InputState), *S,
+ transfer(StmtToEnvMap(AC.ACFG, AC.BlockStates, CurBlockID, InputState), *S,
InputState.Env);
}
@@ -511,9 +510,8 @@ transferCFGBlock(const CFGBlock &Block, AnalysisContext &AC,
// takes a `CFGElement` as input, but some expressions only show up as a
// terminator condition, but not as a `CFGElement`. The condition of an if
// statement is one such example.
- transfer(
- StmtToEnvMap(AC.CFCtx, AC.BlockStates, Block.getBlockID(), State),
- *TerminatorCond, State.Env);
+ transfer(StmtToEnvMap(AC.ACFG, AC.BlockStates, Block.getBlockID(), State),
+ *TerminatorCond, State.Env);
// If the transfer function didn't produce a value, create an atom so that
// we have *some* value for the condition expression. This ensures that
@@ -528,13 +526,13 @@ transferCFGBlock(const CFGBlock &Block, AnalysisContext &AC,
llvm::Expected<std::vector<std::optional<TypeErasedDataflowAnalysisState>>>
runTypeErasedDataflowAnalysis(
- const ControlFlowContext &CFCtx, TypeErasedDataflowAnalysis &Analysis,
+ const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis,
const Environment &InitEnv,
std::function<void(const CFGElement &,
const TypeErasedDataflowAnalysisState &)>
PostVisitCFG,
std::int32_t MaxBlockVisits) {
- PrettyStackTraceAnalysis CrashInfo(CFCtx, "runTypeErasedDataflowAnalysis");
+ PrettyStackTraceAnalysis CrashInfo(ACFG, "runTypeErasedDataflowAnalysis");
std::optional<Environment> MaybeStartingEnv;
if (InitEnv.callStackSize() == 1) {
@@ -544,7 +542,7 @@ runTypeErasedDataflowAnalysis(
const Environment &StartingEnv =
MaybeStartingEnv ? *MaybeStartingEnv : InitEnv;
- const clang::CFG &CFG = CFCtx.getCFG();
+ const clang::CFG &CFG = ACFG.getCFG();
PostOrderCFGView POV(&CFG);
ForwardDataflowWorklist Worklist(CFG, &POV);
@@ -557,7 +555,7 @@ runTypeErasedDataflowAnalysis(
StartingEnv.fork()};
Worklist.enqueueSuccessors(&Entry);
- AnalysisContext AC(CFCtx, Analysis, StartingEnv, BlockStates);
+ AnalysisContext AC(ACFG, Analysis, StartingEnv, BlockStates);
std::int32_t BlockVisits = 0;
while (const CFGBlock *Block = Worklist.dequeue()) {
LLVM_DEBUG(llvm::dbgs()
@@ -615,7 +613,7 @@ runTypeErasedDataflowAnalysis(
// state set to `std::nullopt` at this point) to also analyze dead code.
if (PostVisitCFG) {
- for (const CFGBlock *Block : CFCtx.getCFG()) {
+ for (const CFGBlock *Block : ACFG.getCFG()) {
// Skip blocks that were not evaluated.
if (!BlockStates[Block->getBlockID()])
continue;