@@ -49,6 +49,7 @@ void unwindsett::parse_unwindset_one_loop(std::string val)
49
49
// The loop id can take three forms:
50
50
// 1) Just a function name to limit recursion.
51
51
// 2) F.N where F is a function name and N is a loop number.
52
+ // 3) F.L where F is a function name and L is a label.
52
53
const symbol_tablet &symbol_table = goto_model.get_symbol_table ();
53
54
const symbolt *maybe_fn = symbol_table.lookup (id);
54
55
if (maybe_fn && maybe_fn->type .id () == ID_code)
@@ -99,8 +100,33 @@ void unwindsett::parse_unwindset_one_loop(std::string val)
99
100
}
100
101
else
101
102
{
102
- throw invalid_command_line_argument_exceptiont{
103
- " invalid loop identifier " + id, " unwindset" };
103
+ optionalt<unsigned > nr;
104
+ optionalt<source_locationt> location;
105
+ for (const auto &instruction : goto_function.body .instructions )
106
+ {
107
+ if (
108
+ std::find (
109
+ instruction.labels .begin (),
110
+ instruction.labels .end (),
111
+ loop_nr_label) != instruction.labels .end ())
112
+ {
113
+ location = instruction.source_location ();
114
+ }
115
+ if (
116
+ location.has_value () && instruction.is_backwards_goto () &&
117
+ instruction.source_location () == *location)
118
+ {
119
+ nr = instruction.loop_number ;
120
+ break ;
121
+ }
122
+ }
123
+ if (!nr.has_value ())
124
+ {
125
+ throw invalid_command_line_argument_exceptiont{
126
+ " loop identifier " + id + " does not match any loop" , " unwindset" };
127
+ }
128
+ else
129
+ id = function_id + " ." + std::to_string (*nr);
104
130
}
105
131
}
106
132
0 commit comments