Skip to content

Commit c95cb4d

Browse files
committed
[clang][dataflow] Intersect ExprToLoc when joining environments
This is part of the implementation of the dataflow analysis framework. See "[RFC] A dataflow analysis framework for Clang AST" on cfe-dev. Reviewed-by: xazax.hun Differential Revision: https://reviews.llvm.org/D117754
1 parent 010a10b commit c95cb4d

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ LatticeJoinEffect Environment::join(const Environment &Other) {
8383
if (DeclToLocSizeBefore != DeclToLoc.size())
8484
Effect = LatticeJoinEffect::Changed;
8585

86+
const unsigned ExprToLocSizeBefore = ExprToLoc.size();
87+
ExprToLoc = intersectDenseMaps(ExprToLoc, Other.ExprToLoc);
88+
if (ExprToLocSizeBefore != ExprToLoc.size())
89+
Effect = LatticeJoinEffect::Changed;
90+
8691
// FIXME: Add support for joining distinct values that are assigned to the
8792
// same storage locations in `LocToVal` and `Other.LocToVal`.
8893
const unsigned LocToValSizeBefore = LocToVal.size();

clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "clang/Analysis/FlowSensitive/Transfer.h"
2424
#include "clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
2525
#include "clang/Analysis/FlowSensitive/Value.h"
26+
#include "llvm/ADT/DenseSet.h"
2627
#include "llvm/ADT/None.h"
2728
#include "llvm/ADT/Optional.h"
2829
#include "llvm/Support/raw_ostream.h"

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,4 +1828,41 @@ TEST_F(TransferTest, VarDeclInitAssignConditionalOperator) {
18281828
});
18291829
}
18301830

1831+
TEST_F(TransferTest, VarDeclInDoWhile) {
1832+
std::string Code = R"(
1833+
void target(int *Foo) {
1834+
do {
1835+
int Bar = *Foo;
1836+
} while (true);
1837+
(void)0;
1838+
/*[[p]]*/
1839+
}
1840+
)";
1841+
runDataflow(Code,
1842+
[](llvm::ArrayRef<
1843+
std::pair<std::string, DataflowAnalysisState<NoopLattice>>>
1844+
Results,
1845+
ASTContext &ASTCtx) {
1846+
ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
1847+
const Environment &Env = Results[0].second.Env;
1848+
1849+
const ValueDecl *FooDecl = findValueDecl(ASTCtx, "Foo");
1850+
ASSERT_THAT(FooDecl, NotNull());
1851+
1852+
const ValueDecl *BarDecl = findValueDecl(ASTCtx, "Bar");
1853+
ASSERT_THAT(BarDecl, NotNull());
1854+
1855+
const auto *FooVal =
1856+
cast<PointerValue>(Env.getValue(*FooDecl, SkipPast::None));
1857+
const auto *FooPointeeVal =
1858+
cast<IntegerValue>(Env.getValue(FooVal->getPointeeLoc()));
1859+
1860+
const auto *BarVal = dyn_cast_or_null<IntegerValue>(
1861+
Env.getValue(*BarDecl, SkipPast::None));
1862+
ASSERT_THAT(BarVal, NotNull());
1863+
1864+
EXPECT_EQ(BarVal, FooPointeeVal);
1865+
});
1866+
}
1867+
18311868
} // namespace

0 commit comments

Comments
 (0)