Skip to content

Commit a79be10

Browse files
SC llvm teamSC llvm team
authored andcommitted
Merged main:eac68447adac3852524c66acac7ab64d90205f47 into amd-gfx:b12f0cb54b03
Local branch amd-gfx b12f0cb Merged main:ff60a84f04b4d8af63d581d4f9dd7ab0196a200e into amd-gfx:f11aa52a9799 Remote branch main eac6844 [gn build] Port 59ff3ad
2 parents b12f0cb + eac6844 commit a79be10

File tree

28 files changed

+266
-196
lines changed

28 files changed

+266
-196
lines changed

clang/docs/tools/clang-formatted-files.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ clang/include/clang/Analysis/MacroExpansionContext.h
122122
clang/include/clang/Analysis/Analyses/CalledOnceCheck.h
123123
clang/include/clang/Analysis/Analyses/CFGReachabilityAnalysis.h
124124
clang/include/clang/Analysis/Analyses/ExprMutationAnalyzer.h
125+
clang/include/clang/Analysis/FlowSensitive/AdornedCFG.h
125126
clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
126127
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
127128
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
@@ -306,7 +307,7 @@ clang/include/clang-c/Index.h
306307
clang/lib/Analysis/CalledOnceCheck.cpp
307308
clang/lib/Analysis/CloneDetection.cpp
308309
clang/lib/Analysis/CodeInjector.cpp
309-
clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp
310+
clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp
310311
clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
311312
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
312313
clang/lib/Analysis/FlowSensitive/DebugSupport.cpp
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
//===-- AdornedCFG.h ------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines an AdornedCFG class that is used by dataflow analyses that
10+
// run over Control-Flow Graphs (CFGs).
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H
15+
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H
16+
17+
#include "clang/AST/ASTContext.h"
18+
#include "clang/AST/Decl.h"
19+
#include "clang/AST/Stmt.h"
20+
#include "clang/Analysis/CFG.h"
21+
#include "llvm/ADT/BitVector.h"
22+
#include "llvm/ADT/DenseMap.h"
23+
#include "llvm/Support/Error.h"
24+
#include <memory>
25+
#include <utility>
26+
27+
namespace clang {
28+
namespace dataflow {
29+
30+
/// Holds CFG with additional information derived from it that is needed to
31+
/// perform dataflow analysis.
32+
class AdornedCFG {
33+
public:
34+
/// Builds an `AdornedCFG` from a `FunctionDecl`.
35+
/// `Func.doesThisDeclarationHaveABody()` must be true, and
36+
/// `Func.isTemplated()` must be false.
37+
static llvm::Expected<AdornedCFG> build(const FunctionDecl &Func);
38+
39+
/// Builds an `AdornedCFG` from an AST node. `D` is the function in which
40+
/// `S` resides. `D.isTemplated()` must be false.
41+
static llvm::Expected<AdornedCFG> build(const Decl &D, Stmt &S,
42+
ASTContext &C);
43+
44+
/// Returns the `Decl` containing the statement used to construct the CFG, if
45+
/// available.
46+
const Decl &getDecl() const { return ContainingDecl; }
47+
48+
/// Returns the CFG that is stored in this context.
49+
const CFG &getCFG() const { return *Cfg; }
50+
51+
/// Returns a mapping from statements to basic blocks that contain them.
52+
const llvm::DenseMap<const Stmt *, const CFGBlock *> &getStmtToBlock() const {
53+
return StmtToBlock;
54+
}
55+
56+
/// Returns whether `B` is reachable from the entry block.
57+
bool isBlockReachable(const CFGBlock &B) const {
58+
return BlockReachable[B.getBlockID()];
59+
}
60+
61+
/// Returns whether `B` contains an expression that is consumed in a
62+
/// different block than `B` (i.e. the parent of the expression is in a
63+
/// different block).
64+
/// This happens if there is control flow within a full-expression (triggered
65+
/// by `&&`, `||`, or the conditional operator). Note that the operands of
66+
/// these operators are not the only expressions that can be consumed in a
67+
/// different block. For example, in the function call
68+
/// `f(&i, cond() ? 1 : 0)`, `&i` is in a different block than the `CallExpr`.
69+
bool containsExprConsumedInDifferentBlock(const CFGBlock &B) const {
70+
return ContainsExprConsumedInDifferentBlock.contains(&B);
71+
}
72+
73+
private:
74+
AdornedCFG(
75+
const Decl &D, std::unique_ptr<CFG> Cfg,
76+
llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock,
77+
llvm::BitVector BlockReachable,
78+
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock)
79+
: ContainingDecl(D), Cfg(std::move(Cfg)),
80+
StmtToBlock(std::move(StmtToBlock)),
81+
BlockReachable(std::move(BlockReachable)),
82+
ContainsExprConsumedInDifferentBlock(
83+
std::move(ContainsExprConsumedInDifferentBlock)) {}
84+
85+
/// The `Decl` containing the statement used to construct the CFG.
86+
const Decl &ContainingDecl;
87+
std::unique_ptr<CFG> Cfg;
88+
llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
89+
llvm::BitVector BlockReachable;
90+
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock;
91+
};
92+
93+
} // namespace dataflow
94+
} // namespace clang
95+
96+
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H

clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h

Lines changed: 4 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -6,89 +6,20 @@
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This file defines a ControlFlowContext class that is used by dataflow
10-
// analyses that run over Control-Flow Graphs (CFGs).
9+
// This file defines a deprecated alias for AdornedCFG.
1110
//
1211
//===----------------------------------------------------------------------===//
1312

1413
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H
1514
#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_CONTROLFLOWCONTEXT_H
1615

17-
#include "clang/AST/ASTContext.h"
18-
#include "clang/AST/Decl.h"
19-
#include "clang/AST/Stmt.h"
20-
#include "clang/Analysis/CFG.h"
21-
#include "llvm/ADT/BitVector.h"
22-
#include "llvm/ADT/DenseMap.h"
23-
#include "llvm/Support/Error.h"
24-
#include <memory>
25-
#include <utility>
16+
#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
2617

2718
namespace clang {
2819
namespace dataflow {
2920

30-
/// Holds CFG and other derived context that is needed to perform dataflow
31-
/// analysis.
32-
class ControlFlowContext {
33-
public:
34-
/// Builds a ControlFlowContext from a `FunctionDecl`.
35-
/// `Func.doesThisDeclarationHaveABody()` must be true, and
36-
/// `Func.isTemplated()` must be false.
37-
static llvm::Expected<ControlFlowContext> build(const FunctionDecl &Func);
38-
39-
/// Builds a ControlFlowContext from an AST node. `D` is the function in which
40-
/// `S` resides. `D.isTemplated()` must be false.
41-
static llvm::Expected<ControlFlowContext> build(const Decl &D, Stmt &S,
42-
ASTContext &C);
43-
44-
/// Returns the `Decl` containing the statement used to construct the CFG, if
45-
/// available.
46-
const Decl &getDecl() const { return ContainingDecl; }
47-
48-
/// Returns the CFG that is stored in this context.
49-
const CFG &getCFG() const { return *Cfg; }
50-
51-
/// Returns a mapping from statements to basic blocks that contain them.
52-
const llvm::DenseMap<const Stmt *, const CFGBlock *> &getStmtToBlock() const {
53-
return StmtToBlock;
54-
}
55-
56-
/// Returns whether `B` is reachable from the entry block.
57-
bool isBlockReachable(const CFGBlock &B) const {
58-
return BlockReachable[B.getBlockID()];
59-
}
60-
61-
/// Returns whether `B` contains an expression that is consumed in a
62-
/// different block than `B` (i.e. the parent of the expression is in a
63-
/// different block).
64-
/// This happens if there is control flow within a full-expression (triggered
65-
/// by `&&`, `||`, or the conditional operator). Note that the operands of
66-
/// these operators are not the only expressions that can be consumed in a
67-
/// different block. For example, in the function call
68-
/// `f(&i, cond() ? 1 : 0)`, `&i` is in a different block than the `CallExpr`.
69-
bool containsExprConsumedInDifferentBlock(const CFGBlock &B) const {
70-
return ContainsExprConsumedInDifferentBlock.contains(&B);
71-
}
72-
73-
private:
74-
ControlFlowContext(
75-
const Decl &D, std::unique_ptr<CFG> Cfg,
76-
llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock,
77-
llvm::BitVector BlockReachable,
78-
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock)
79-
: ContainingDecl(D), Cfg(std::move(Cfg)),
80-
StmtToBlock(std::move(StmtToBlock)),
81-
BlockReachable(std::move(BlockReachable)),
82-
ContainsExprConsumedInDifferentBlock(
83-
std::move(ContainsExprConsumedInDifferentBlock)) {}
84-
85-
/// The `Decl` containing the statement used to construct the CFG.
86-
const Decl &ContainingDecl;
87-
std::unique_ptr<CFG> Cfg;
88-
llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
89-
llvm::BitVector BlockReachable;
90-
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock;
91-
};
21+
// This is a deprecated alias. Use `AdornedCFG` instead.
22+
using ControlFlowContext = AdornedCFG;
9223

9324
} // namespace dataflow
9425
} // namespace clang

clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
#include "clang/AST/ASTContext.h"
2424
#include "clang/Analysis/CFG.h"
25-
#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
25+
#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
2626
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
2727
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
2828
#include "clang/Analysis/FlowSensitive/MatchSwitch.h"
@@ -195,8 +195,7 @@ template <typename AnalysisT>
195195
llvm::Expected<std::vector<
196196
std::optional<DataflowAnalysisState<typename AnalysisT::Lattice>>>>
197197
runDataflowAnalysis(
198-
const ControlFlowContext &CFCtx, AnalysisT &Analysis,
199-
const Environment &InitEnv,
198+
const AdornedCFG &ACFG, AnalysisT &Analysis, const Environment &InitEnv,
200199
std::function<void(const CFGElement &, const DataflowAnalysisState<
201200
typename AnalysisT::Lattice> &)>
202201
PostVisitCFG = nullptr,
@@ -218,7 +217,7 @@ runDataflowAnalysis(
218217
}
219218

220219
auto TypeErasedBlockStates = runTypeErasedDataflowAnalysis(
221-
CFCtx, Analysis, InitEnv, PostVisitCFGClosure, MaxBlockVisits);
220+
ACFG, Analysis, InitEnv, PostVisitCFGClosure, MaxBlockVisits);
222221
if (!TypeErasedBlockStates)
223222
return TypeErasedBlockStates.takeError();
224223

@@ -280,8 +279,7 @@ llvm::Expected<llvm::SmallVector<Diagnostic>> diagnoseFunction(
280279
Diagnoser,
281280
std::int64_t MaxSATIterations = 1'000'000'000,
282281
std::int32_t MaxBlockVisits = 20'000) {
283-
llvm::Expected<ControlFlowContext> Context =
284-
ControlFlowContext::build(FuncDecl);
282+
llvm::Expected<AdornedCFG> Context = AdornedCFG::build(FuncDecl);
285283
if (!Context)
286284
return Context.takeError();
287285

clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
#include "clang/AST/Decl.h"
1919
#include "clang/AST/Expr.h"
2020
#include "clang/AST/TypeOrdering.h"
21+
#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
2122
#include "clang/Analysis/FlowSensitive/Arena.h"
22-
#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
2323
#include "clang/Analysis/FlowSensitive/Solver.h"
2424
#include "clang/Analysis/FlowSensitive/StorageLocation.h"
2525
#include "clang/Analysis/FlowSensitive/Value.h"
@@ -183,9 +183,9 @@ class DataflowAnalysisContext {
183183
LLVM_DUMP_METHOD void dumpFlowCondition(Atom Token,
184184
llvm::raw_ostream &OS = llvm::dbgs());
185185

186-
/// Returns the `ControlFlowContext` registered for `F`, if any. Otherwise,
186+
/// Returns the `AdornedCFG` registered for `F`, if any. Otherwise,
187187
/// returns null.
188-
const ControlFlowContext *getControlFlowContext(const FunctionDecl *F);
188+
const AdornedCFG *getAdornedCFG(const FunctionDecl *F);
189189

190190
const Options &getOptions() { return Opts; }
191191

@@ -296,7 +296,7 @@ class DataflowAnalysisContext {
296296
llvm::DenseMap<Atom, const Formula *> FlowConditionConstraints;
297297
const Formula *Invariant = nullptr;
298298

299-
llvm::DenseMap<const FunctionDecl *, ControlFlowContext> FunctionContexts;
299+
llvm::DenseMap<const FunctionDecl *, AdornedCFG> FunctionContexts;
300300

301301
// Fields modeled by environments covered by this context.
302302
FieldSet ModeledFields;

clang/include/clang/Analysis/FlowSensitive/Logger.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
namespace clang::dataflow {
1717
// Forward declarations so we can use Logger anywhere in the framework.
18-
class ControlFlowContext;
18+
class AdornedCFG;
1919
class TypeErasedDataflowAnalysis;
2020
struct TypeErasedDataflowAnalysisState;
2121

@@ -40,8 +40,8 @@ class Logger {
4040

4141
/// Called by the framework as we start analyzing a new function or statement.
4242
/// Forms a pair with endAnalysis().
43-
virtual void beginAnalysis(const ControlFlowContext &,
44-
TypeErasedDataflowAnalysis &) {}
43+
virtual void beginAnalysis(const AdornedCFG &, TypeErasedDataflowAnalysis &) {
44+
}
4545
virtual void endAnalysis() {}
4646

4747
// At any time during the analysis, we're computing the state for some target

clang/include/clang/Analysis/FlowSensitive/Transfer.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,20 +29,20 @@ class StmtToEnvMap {
2929
// `CurState` is the pending state currently associated with this block. These
3030
// are supplied separately as the pending state for the current block may not
3131
// yet be represented in `BlockToState`.
32-
StmtToEnvMap(const ControlFlowContext &CFCtx,
32+
StmtToEnvMap(const AdornedCFG &ACFG,
3333
llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>>
3434
BlockToState,
3535
unsigned CurBlockID,
3636
const TypeErasedDataflowAnalysisState &CurState)
37-
: CFCtx(CFCtx), BlockToState(BlockToState), CurBlockID(CurBlockID),
37+
: ACFG(ACFG), BlockToState(BlockToState), CurBlockID(CurBlockID),
3838
CurState(CurState) {}
3939

4040
/// Returns the environment of the basic block that contains `S`.
4141
/// The result is guaranteed never to be null.
4242
const Environment *getEnvironment(const Stmt &S) const;
4343

4444
private:
45-
const ControlFlowContext &CFCtx;
45+
const AdornedCFG &ACFG;
4646
llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>> BlockToState;
4747
unsigned CurBlockID;
4848
const TypeErasedDataflowAnalysisState &CurState;

clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include "clang/AST/ASTContext.h"
2222
#include "clang/AST/Stmt.h"
2323
#include "clang/Analysis/CFG.h"
24-
#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
24+
#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
2525
#include "clang/Analysis/FlowSensitive/DataflowAnalysisContext.h"
2626
#include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
2727
#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
@@ -146,7 +146,7 @@ struct TypeErasedDataflowAnalysisState {
146146
/// from converging.
147147
llvm::Expected<std::vector<std::optional<TypeErasedDataflowAnalysisState>>>
148148
runTypeErasedDataflowAnalysis(
149-
const ControlFlowContext &CFCtx, TypeErasedDataflowAnalysis &Analysis,
149+
const AdornedCFG &ACFG, TypeErasedDataflowAnalysis &Analysis,
150150
const Environment &InitEnv,
151151
std::function<void(const CFGElement &,
152152
const TypeErasedDataflowAnalysisState &)>

clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp renamed to clang/lib/Analysis/FlowSensitive/AdornedCFG.cpp

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
//===- ControlFlowContext.cpp ---------------------------------------------===//
1+
//===- AdornedCFG.cpp ---------------------------------------------===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
88
//
9-
// This file defines a ControlFlowContext class that is used by dataflow
10-
// analyses that run over Control-Flow Graphs (CFGs).
9+
// This file defines an `AdornedCFG` class that is used by dataflow analyses
10+
// that run over Control-Flow Graphs (CFGs).
1111
//
1212
//===----------------------------------------------------------------------===//
1313

14-
#include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
14+
#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
1515
#include "clang/AST/ASTContext.h"
1616
#include "clang/AST/Decl.h"
1717
#include "clang/AST/Stmt.h"
@@ -126,8 +126,7 @@ buildContainsExprConsumedInDifferentBlock(
126126
return Result;
127127
}
128128

129-
llvm::Expected<ControlFlowContext>
130-
ControlFlowContext::build(const FunctionDecl &Func) {
129+
llvm::Expected<AdornedCFG> AdornedCFG::build(const FunctionDecl &Func) {
131130
if (!Func.doesThisDeclarationHaveABody())
132131
return llvm::createStringError(
133132
std::make_error_code(std::errc::invalid_argument),
@@ -136,8 +135,8 @@ ControlFlowContext::build(const FunctionDecl &Func) {
136135
return build(Func, *Func.getBody(), Func.getASTContext());
137136
}
138137

139-
llvm::Expected<ControlFlowContext>
140-
ControlFlowContext::build(const Decl &D, Stmt &S, ASTContext &C) {
138+
llvm::Expected<AdornedCFG> AdornedCFG::build(const Decl &D, Stmt &S,
139+
ASTContext &C) {
141140
if (D.isTemplated())
142141
return llvm::createStringError(
143142
std::make_error_code(std::errc::invalid_argument),
@@ -175,9 +174,9 @@ ControlFlowContext::build(const Decl &D, Stmt &S, ASTContext &C) {
175174
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock =
176175
buildContainsExprConsumedInDifferentBlock(*Cfg, StmtToBlock);
177176

178-
return ControlFlowContext(D, std::move(Cfg), std::move(StmtToBlock),
179-
std::move(BlockReachable),
180-
std::move(ContainsExprConsumedInDifferentBlock));
177+
return AdornedCFG(D, std::move(Cfg), std::move(StmtToBlock),
178+
std::move(BlockReachable),
179+
std::move(ContainsExprConsumedInDifferentBlock));
181180
}
182181

183182
} // namespace dataflow

0 commit comments

Comments
 (0)