@@ -12,12 +12,22 @@ Author: Daniel Kroening, kroening@kroening.com
12
12
#include " remove_skip.h"
13
13
#include " goto_model.h"
14
14
15
- bool is_skip (const goto_programt &body, goto_programt::const_targett it)
15
+ // / Determine whether the instruction is semantically equivalent to a skip
16
+ // / (no-op). This includes a skip, but also if(false) goto ..., goto next;
17
+ // / next: ..., and (void)0.
18
+ // / \param body goto program containing the instruction
19
+ // / \param it instruction iterator that is tested for being a skip (or
20
+ // / equivalent)
21
+ // / \param ignore_labels If the caller takes care of moving labels, then even
22
+ // / skip statements carrying labels can be treated as skips (even though they
23
+ // / may carry key information such as error labels).
24
+ // / \return True, iff it is equivalent to a skip.
25
+ bool is_skip (
26
+ const goto_programt &body,
27
+ goto_programt::const_targett it,
28
+ bool ignore_labels)
16
29
{
17
- // we won't remove labelled statements
18
- // (think about error labels or the like)
19
-
20
- if (!it->labels .empty ())
30
+ if (!ignore_labels && !it->labels .empty ())
21
31
return false ;
22
32
23
33
if (it->is_skip ())
@@ -100,12 +110,17 @@ void remove_skip(
100
110
// for collecting labels
101
111
std::list<irep_idt> labels;
102
112
103
- while (is_skip (goto_program, it))
113
+ while (is_skip (goto_program, it, true ))
104
114
{
105
115
// don't remove the last skip statement,
106
116
// it could be a target
107
- if (it == std::prev (end))
117
+ if (
118
+ it == std::prev (end) ||
119
+ (std::next (it)->is_end_function () &&
120
+ (!labels.empty () || !it->labels .empty ())))
121
+ {
108
122
break ;
123
+ }
109
124
110
125
// save labels
111
126
labels.splice (labels.end (), it->labels );
0 commit comments