Skip to content

Commit 2cdb6b8

Browse files
bazuziymand
authored andcommitted
[clang][dataflow] Expose DataflowAnalysisContext from DataflowEnvironment.
This will eliminate the need for more pass-through APIs. Also replace pass-through usages with this exposure. Reviewed By: ymandel, gribozavr2, xazax.hun Differential Revision: https://reviews.llvm.org/D149464
1 parent 084ca63 commit 2cdb6b8

File tree

6 files changed

+40
-25
lines changed

6 files changed

+40
-25
lines changed

clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "clang/Analysis/FlowSensitive/Value.h"
2828
#include "llvm/ADT/DenseMap.h"
2929
#include "llvm/ADT/DenseSet.h"
30+
#include "llvm/Support/Compiler.h"
3031
#include "llvm/Support/ErrorHandling.h"
3132
#include <memory>
3233
#include <type_traits>
@@ -178,12 +179,16 @@ class Environment {
178179
/// with a symbolic representation of the `this` pointee.
179180
Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx);
180181

182+
LLVM_DEPRECATED("Use getDataflowAnalysisContext().getOptions() instead.", "")
181183
const DataflowAnalysisContext::Options &getAnalysisOptions() const {
182184
return DACtx->getOptions();
183185
}
184186

187+
LLVM_DEPRECATED("Use getDataflowAnalysisContext().arena() instead.", "")
185188
Arena &arena() const { return DACtx->arena(); }
186189

190+
LLVM_DEPRECATED("Use getDataflowAnalysisContext().getOptions().Log instead.",
191+
"")
187192
Logger &logger() const { return *DACtx->getOptions().Log; }
188193

189194
/// Creates and returns an environment to use for an inline analysis of the
@@ -331,61 +336,61 @@ class Environment {
331336
template <typename T, typename... Args>
332337
std::enable_if_t<std::is_base_of<Value, T>::value, T &>
333338
create(Args &&...args) {
334-
return arena().create<T>(std::forward<Args>(args)...);
339+
return DACtx->arena().create<T>(std::forward<Args>(args)...);
335340
}
336341

337342
/// Returns a symbolic boolean value that models a boolean literal equal to
338343
/// `Value`
339344
AtomicBoolValue &getBoolLiteralValue(bool Value) const {
340-
return arena().makeLiteral(Value);
345+
return DACtx->arena().makeLiteral(Value);
341346
}
342347

343348
/// Returns an atomic boolean value.
344349
BoolValue &makeAtomicBoolValue() const {
345-
return arena().create<AtomicBoolValue>();
350+
return DACtx->arena().create<AtomicBoolValue>();
346351
}
347352

348353
/// Returns a unique instance of boolean Top.
349354
BoolValue &makeTopBoolValue() const {
350-
return arena().create<TopBoolValue>();
355+
return DACtx->arena().create<TopBoolValue>();
351356
}
352357

353358
/// Returns a boolean value that represents the conjunction of `LHS` and
354359
/// `RHS`. Subsequent calls with the same arguments, regardless of their
355360
/// order, will return the same result. If the given boolean values represent
356361
/// the same value, the result will be the value itself.
357362
BoolValue &makeAnd(BoolValue &LHS, BoolValue &RHS) const {
358-
return arena().makeAnd(LHS, RHS);
363+
return DACtx->arena().makeAnd(LHS, RHS);
359364
}
360365

361366
/// Returns a boolean value that represents the disjunction of `LHS` and
362367
/// `RHS`. Subsequent calls with the same arguments, regardless of their
363368
/// order, will return the same result. If the given boolean values represent
364369
/// the same value, the result will be the value itself.
365370
BoolValue &makeOr(BoolValue &LHS, BoolValue &RHS) const {
366-
return arena().makeOr(LHS, RHS);
371+
return DACtx->arena().makeOr(LHS, RHS);
367372
}
368373

369374
/// Returns a boolean value that represents the negation of `Val`. Subsequent
370375
/// calls with the same argument will return the same result.
371376
BoolValue &makeNot(BoolValue &Val) const {
372-
return arena().makeNot(Val);
377+
return DACtx->arena().makeNot(Val);
373378
}
374379

375380
/// Returns a boolean value represents `LHS` => `RHS`. Subsequent calls with
376381
/// the same arguments, will return the same result. If the given boolean
377382
/// values represent the same value, the result will be a value that
378383
/// represents the true boolean literal.
379384
BoolValue &makeImplication(BoolValue &LHS, BoolValue &RHS) const {
380-
return arena().makeImplies(LHS, RHS);
385+
return DACtx->arena().makeImplies(LHS, RHS);
381386
}
382387

383388
/// Returns a boolean value represents `LHS` <=> `RHS`. Subsequent calls with
384389
/// the same arguments, regardless of their order, will return the same
385390
/// result. If the given boolean values represent the same value, the result
386391
/// will be a value that represents the true boolean literal.
387392
BoolValue &makeIff(BoolValue &LHS, BoolValue &RHS) const {
388-
return arena().makeEquals(LHS, RHS);
393+
return DACtx->arena().makeEquals(LHS, RHS);
389394
}
390395

391396
/// Returns the token that identifies the flow condition of the environment.
@@ -409,10 +414,15 @@ class Environment {
409414

410415
/// Returns the `ControlFlowContext` registered for `F`, if any. Otherwise,
411416
/// returns null.
417+
LLVM_DEPRECATED(
418+
"Use getDataflowAnalysisContext().getControlFlowContext(F) instead.", "")
412419
const ControlFlowContext *getControlFlowContext(const FunctionDecl *F) {
413420
return DACtx->getControlFlowContext(F);
414421
}
415422

423+
/// Returns the `DataflowAnalysisContext` used by the environment.
424+
DataflowAnalysisContext &getDataflowAnalysisContext() const { return *DACtx; }
425+
416426
LLVM_DUMP_METHOD void dump() const;
417427
LLVM_DUMP_METHOD void dump(raw_ostream &OS) const;
418428

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ void Environment::pushCallInternal(const FunctionDecl *FuncDecl,
381381

382382
QualType ParamType = Param->getType();
383383
if (ParamType->isReferenceType()) {
384-
auto &Val = arena().create<ReferenceValue>(*ArgLoc);
384+
auto &Val = DACtx->arena().create<ReferenceValue>(*ArgLoc);
385385
setValue(Loc, Val);
386386
} else if (auto *ArgVal = getValue(*ArgLoc)) {
387387
setValue(Loc, *ArgVal);
@@ -707,7 +707,7 @@ Value *Environment::createValueUnlessSelfReferential(
707707
// with integers, and so distinguishing them serves no purpose, but could
708708
// prevent convergence.
709709
CreatedValuesCount++;
710-
return &arena().create<IntegerValue>();
710+
return &DACtx->arena().create<IntegerValue>();
711711
}
712712

713713
if (Type->isReferenceType() || Type->isPointerType()) {
@@ -725,9 +725,9 @@ Value *Environment::createValueUnlessSelfReferential(
725725
}
726726

727727
if (Type->isReferenceType())
728-
return &arena().create<ReferenceValue>(PointeeLoc);
728+
return &DACtx->arena().create<ReferenceValue>(PointeeLoc);
729729
else
730-
return &arena().create<PointerValue>(PointeeLoc);
730+
return &DACtx->arena().create<PointerValue>(PointeeLoc);
731731
}
732732

733733
if (Type->isRecordType()) {
@@ -747,7 +747,7 @@ Value *Environment::createValueUnlessSelfReferential(
747747
Visited.erase(FieldType.getCanonicalType());
748748
}
749749

750-
return &arena().create<StructValue>(std::move(FieldValues));
750+
return &DACtx->arena().create<StructValue>(std::move(FieldValues));
751751
}
752752

753753
return nullptr;

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
496496
}
497497

498498
void VisitReturnStmt(const ReturnStmt *S) {
499-
if (!Env.getAnalysisOptions().ContextSensitiveOpts)
499+
if (!Env.getDataflowAnalysisContext().getOptions().ContextSensitiveOpts)
500500
return;
501501

502502
auto *Ret = S->getRetValue();
@@ -863,12 +863,13 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
863863
// `F` of `S`. The type `E` must be either `CallExpr` or `CXXConstructExpr`.
864864
template <typename E>
865865
void transferInlineCall(const E *S, const FunctionDecl *F) {
866-
const auto &Options = Env.getAnalysisOptions();
866+
const auto &Options = Env.getDataflowAnalysisContext().getOptions();
867867
if (!(Options.ContextSensitiveOpts &&
868868
Env.canDescend(Options.ContextSensitiveOpts->Depth, F)))
869869
return;
870870

871-
const ControlFlowContext *CFCtx = Env.getControlFlowContext(F);
871+
const ControlFlowContext *CFCtx =
872+
Env.getDataflowAnalysisContext().getControlFlowContext(F);
872873
if (!CFCtx)
873874
return;
874875

clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ struct AnalysisContext {
168168
llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>>
169169
BlockStates)
170170
: CFCtx(CFCtx), Analysis(Analysis), InitEnv(InitEnv),
171-
Log(InitEnv.logger()), BlockStates(BlockStates) {
171+
Log(*InitEnv.getDataflowAnalysisContext().getOptions().Log),
172+
BlockStates(BlockStates) {
172173
Log.beginAnalysis(CFCtx, Analysis);
173174
}
174175
~AnalysisContext() { Log.endAnalysis(); }

clang/unittests/Analysis/FlowSensitive/LoggerTest.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,16 @@ class TestAnalysis : public DataflowAnalysis<TestAnalysis, TestLattice> {
3737

3838
static TestLattice initialElement() { return TestLattice{}; }
3939
void transfer(const CFGElement &, TestLattice &L, Environment &E) {
40-
E.logger().log([](llvm::raw_ostream &OS) { OS << "transfer()"; });
40+
E.getDataflowAnalysisContext().getOptions().Log->log(
41+
[](llvm::raw_ostream &OS) { OS << "transfer()"; });
4142
++L.Elements;
4243
}
4344
void transferBranch(bool Branch, const Stmt *S, TestLattice &L,
4445
Environment &E) {
45-
E.logger().log([&](llvm::raw_ostream &OS) {
46-
OS << "transferBranch(" << Branch << ")";
47-
});
46+
E.getDataflowAnalysisContext().getOptions().Log->log(
47+
[&](llvm::raw_ostream &OS) {
48+
OS << "transferBranch(" << Branch << ")";
49+
});
4850
++L.Branches;
4951
}
5052
};

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@ void runDataflow(llvm::StringRef Code, Matcher Match,
5353
[UseBuiltinModel = Options.BuiltinOpts.has_value()](ASTContext &C,
5454
Environment &Env) {
5555
return NoopAnalysis(
56-
C, DataflowAnalysisOptions{UseBuiltinModel
57-
? Env.getAnalysisOptions()
58-
: std::optional<BuiltinOptions>()});
56+
C,
57+
DataflowAnalysisOptions{
58+
UseBuiltinModel ? Env.getDataflowAnalysisContext().getOptions()
59+
: std::optional<BuiltinOptions>()});
5960
});
6061
AI.ASTBuildArgs = ASTBuildArgs;
6162
if (Options.BuiltinOpts)

0 commit comments

Comments
 (0)