@@ -12,12 +12,22 @@ Author: Daniel Kroening, kroening@kroening.com
1212#include " remove_skip.h"
1313#include " goto_model.h"
1414
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)
1629{
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 ())
2131 return false ;
2232
2333 if (it->is_skip ())
@@ -100,12 +110,17 @@ void remove_skip(
100110 // for collecting labels
101111 std::list<irep_idt> labels;
102112
103- while (is_skip (goto_program, it))
113+ while (is_skip (goto_program, it, true ))
104114 {
105115 // don't remove the last skip statement,
106116 // 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+ {
108122 break ;
123+ }
109124
110125 // save labels
111126 labels.splice (labels.end (), it->labels );
0 commit comments