Skip to content

Commit f69ce86

Browse files
committed
Analysis: Add a CFG successor to a SwitchStmt if it is both empty and fully covered
Consider the case where a SwitchStmt satisfied isAllEnumCasesCovered() as well as having no cases at all (i.e. the enum it covers has no enumerators). In this case, we should add a successor to repair the CFG. This fixes PR16212. llvm-svn: 183237
1 parent 33a35df commit f69ce86

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

clang/lib/Analysis/CFG.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -2671,9 +2671,15 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) {
26712671
// If we have no "default:" case, the default transition is to the code
26722672
// following the switch body. Moreover, take into account if all the
26732673
// cases of a switch are covered (e.g., switching on an enum value).
2674+
//
2675+
// Note: We add a successor to a switch that is considered covered yet has no
2676+
// case statements if the enumeration has no enumerators.
2677+
bool SwitchAlwaysHasSuccessor = false;
2678+
SwitchAlwaysHasSuccessor |= switchExclusivelyCovered;
2679+
SwitchAlwaysHasSuccessor |= Terminator->isAllEnumCasesCovered() &&
2680+
Terminator->getSwitchCaseList();
26742681
addSuccessor(SwitchTerminatedBlock,
2675-
switchExclusivelyCovered || Terminator->isAllEnumCasesCovered()
2676-
? 0 : DefaultCaseBlock);
2682+
SwitchAlwaysHasSuccessor ? 0 : DefaultCaseBlock);
26772683

26782684
// Add the terminator and condition in the switch block.
26792685
SwitchTerminatedBlock->setTerminator(Terminator);

clang/test/Analysis/cfg.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,19 @@ void checkDeclStmts() {
6666

6767
static_assert(1, "abc");
6868
}
69+
70+
// CHECK: ENTRY
71+
// CHECK-NEXT: Succs (1): B1
72+
// CHECK: [B1]
73+
// CHECK-NEXT: 1: e
74+
// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, LValueToRValue, enum EmptyE)
75+
// CHECK-NEXT: 3: [B1.2] (ImplicitCastExpr, IntegralCast, int)
76+
// CHECK-NEXT: T: switch [B1.3]
77+
// CHECK-NEXT: Preds (1): B2
78+
// CHECK-NEXT: Succs (1): B0
79+
// CHECK: [B0 (EXIT)]
80+
// CHECK-NEXT: Preds (1): B1
81+
enum EmptyE {};
82+
void F(EmptyE e) {
83+
switch (e) {}
84+
}

0 commit comments

Comments
 (0)