Skip to content

Commit 8e1d2f2

Browse files
authored
[clang][dataflow] Don't crash when BlockToState is called from unreachable path (#65732)
When we call `getEnvironment`, `BlockToState[BlockId]` for the block can return null even if CFCtx.isBlockReachable(B) returns true if it is called from a particular block that is marked unreachable to the block.
1 parent df45557 commit 8e1d2f2

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,20 @@ const Environment *StmtToEnvMap::getEnvironment(const Stmt &S) const {
4343
if (!CFCtx.isBlockReachable(*BlockIt->getSecond()))
4444
return nullptr;
4545
const auto &State = BlockToState[BlockIt->getSecond()->getBlockID()];
46-
assert(State);
46+
if (!(State)) {
47+
LLVM_DEBUG({
48+
// State can be null when this block is unreachable from the block that
49+
// called this method.
50+
bool hasUnreachableEdgeFromPred = false;
51+
for (auto B : BlockIt->getSecond()->preds())
52+
if (!B) {
53+
hasUnreachableEdgeFromPred = true;
54+
break;
55+
}
56+
assert(hasUnreachableEdgeFromPred);
57+
});
58+
return nullptr;
59+
}
4760
return &State->Env;
4861
}
4962

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5853,4 +5853,24 @@ TEST(TransferTest, AnonymousStructWithReferenceField) {
58535853
});
58545854
}
58555855

5856+
TEST(TransferTest, EvaluateBlockWithUnreachablePreds) {
5857+
// This is a crash repro.
5858+
// `false` block may not have been processed when we try to evalute the `||`
5859+
// after visiting `true`, because it is not necessary (and therefore the edge
5860+
// is marked unreachable). Trying to get the analysis state via
5861+
// `getEnvironment` for the subexpression still should not crash.
5862+
std::string Code = R"(
5863+
int cast(int i) {
5864+
if ((i < 0 && true) || false) {
5865+
return 0;
5866+
}
5867+
return 0;
5868+
}
5869+
)";
5870+
runDataflow(
5871+
Code,
5872+
[](const llvm::StringMap<DataflowAnalysisState<NoopLattice>> &Results,
5873+
ASTContext &ASTCtx) {});
5874+
}
5875+
58565876
} // namespace

0 commit comments

Comments
 (0)