Skip to content

Commit 87ef739

Browse files
committed
Post-dominators: support multiple exit points
Programs with assume(false) or (unconditional) self loops include instructions from which the regular program exit cannot be reached. Nevertheless, such instructions still need to be included in post-dominator computation. Not doing so would result in missing control dependencies when building the dependence graph, and thus in wrong slicing results (which the included regression test previously showed).
1 parent 063f701 commit 87ef739

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
int main()
2+
{
3+
#ifdef __GNUC__
4+
int x = 1;
5+
if(x == 0)
6+
{
7+
__CPROVER_assert(0, "");
8+
// __builtin_types_compatible_p yields a proper "bool" typed constant
9+
__CPROVER_assume(__builtin_types_compatible_p(double, float));
10+
}
11+
#endif
12+
return 0;
13+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
CORE
2+
main.c
3+
--full-slice
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
6+
^SIGNAL=0$

src/analyses/cfg_dominators.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,27 @@ void cfg_dominators_templatet<P, T, post_dom>::fixedpoint(P &program)
163163
++s_it)
164164
worklist.push_back(cfg[s_it->first].PC);
165165

166+
// A program may have multiple "exit" nodes when self loops or assume(false)
167+
// instructions are present.
168+
if(post_dom)
169+
{
170+
for(auto &cfg_entry : cfg.entry_map)
171+
{
172+
if(cfg[cfg_entry.second].PC == entry_node)
173+
continue;
174+
175+
typename cfgt::nodet &n_it = cfg[cfg_entry.second];
176+
if(
177+
n_it.out.empty() ||
178+
(n_it.out.size() == 1 && n_it.out.begin()->first == cfg_entry.second))
179+
{
180+
n_it.dominators.insert(cfg[cfg_entry.second].PC);
181+
for(const auto &predecessor : n_it.in)
182+
worklist.push_back(cfg[predecessor.first].PC);
183+
}
184+
}
185+
}
186+
166187
while(!worklist.empty())
167188
{
168189
// get node from worklist

0 commit comments

Comments
 (0)