Skip to content

Commit 4969295

Browse files
Tidy up remove_instanceof
Sort out and add to the comments Tidy up code for readability Comment about the fact we mutate the instruction list while iterating Replace asserts
1 parent 2716410 commit 4969295

File tree

2 files changed

+57
-49
lines changed

2 files changed

+57
-49
lines changed

src/goto-programs/goto_program_template.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ class goto_program_templatet
361361
}
362362
};
363363

364+
// Never try to change this to vector-we mutate the list while iterating
364365
typedef std::list<instructiont> instructionst;
365366

366367
typedef typename instructionst::iterator targett;

src/goto-programs/remove_instanceof.cpp

Lines changed: 56 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -74,40 +74,53 @@ bool remove_instanceoft::contains_instanceof(
7474
return false;
7575
}
7676

77-
/// Replaces an expression like e instanceof A with e.@class_identifier == "A"
78-
/// Or a big-or of similar expressions if we know of subtypes that also satisfy
77+
/// Replaces an expression like e instanceof A with e.\@class_identifier == "A"
78+
/// or a big-or of similar expressions if we know of subtypes that also satisfy
7979
/// the given test.
80-
/// \par parameters: Expression to lower `expr` and the `goto_program` and
81-
/// instruction `this_inst` it belongs to.
82-
/// \return Side-effect on `expr` replacing it with an explicit clsid test
80+
/// \param expr: Expression to lower (the code or the guard of an instruction)
81+
/// \param goto_program: program the expression belongs to
82+
/// \param this_inst: instruction the expression is found at
83+
/// \param inst_switch: set of instructions to switch around once we're done
8384
void remove_instanceoft::lower_instanceof(
8485
exprt &expr,
8586
goto_programt &goto_program,
8687
goto_programt::targett this_inst,
8788
instanceof_instt &inst_switch)
8889
{
89-
if(expr.id()==ID_java_instanceof)
90+
if(expr.id()!=ID_java_instanceof)
9091
{
92+
Forall_operands(it, expr)
93+
lower_instanceof(*it, goto_program, this_inst, inst_switch);
94+
return;
95+
}
96+
9197
const exprt &check_ptr=expr.op0();
92-
assert(check_ptr.type().id()==ID_pointer);
98+
INVARIANT(
99+
check_ptr.type().id()==ID_pointer,
100+
"instanceof first operand should be a pointer");
93101
const exprt &target_arg=expr.op1();
94-
assert(target_arg.id()==ID_type);
102+
INVARIANT(
103+
target_arg.id()==ID_type,
104+
"instanceof second operand should be a type");
95105
const typet &target_type=target_arg.type();
96106

97107
// Find all types we know about that satisfy the given requirement:
98-
assert(target_type.id()==ID_symbol);
108+
INVARIANT(
109+
target_type.id()==ID_symbol,
110+
"instanceof second operand should have a simple type");
99111
const irep_idt &target_name=
100112
to_symbol_type(target_type).get_identifier();
101113
std::vector<irep_idt> children=
102114
class_hierarchy.get_children_trans(target_name);
103115
children.push_back(target_name);
104116

105-
assert(!children.empty() && "Unable to execute instanceof");
106-
107-
// Insert an instruction before this one that assigns the clsid we're
108-
// checking against to a temporary, as GOTO program if-expressions should
117+
// Insert an instruction before the new check that assigns the clsid we're
118+
// checking for to a temporary, as GOTO program if-expressions should
109119
// not contain derefs.
110-
120+
// We actually insert the assignment instruction after the existing one.
121+
// This will briefly be ill-formed (use before def of instanceof_tmp) but the
122+
// two will subsequently switch places. This makes sure that the inserted
123+
// assignement doesn't end up before any labels pointing at this instruction.
111124
symbol_typet jlo("java::java.lang.Object");
112125
exprt object_clsid=get_class_identifier_field(check_ptr, jlo, ns);
113126

@@ -126,10 +139,7 @@ void remove_instanceoft::lower_instanceof(
126139
newinst->source_location=this_inst->source_location;
127140
newinst->function=this_inst->function;
128141

129-
// Insert the check instruction after the existing one.
130-
// This will briefly be ill-formed (use before def of
131-
// instanceof_tmp) but the two will subsequently switch
132-
// places in lower_instanceof(goto_programt &) below.
142+
// Remember to switch the instructions
133143
inst_switch.push_back(make_pair(this_inst, newinst));
134144
// Replace the instanceof construct with a big-or.
135145
exprt::operandst or_ops;
@@ -140,20 +150,14 @@ void remove_instanceoft::lower_instanceof(
140150
or_ops.push_back(test);
141151
}
142152
expr=disjunction(or_ops);
143-
}
144-
else
145-
{
146-
Forall_operands(it, expr)
147-
lower_instanceof(*it, goto_program, this_inst, inst_switch);
148-
}
149153
}
150154

151-
/// See function above
152-
/// \par parameters: GOTO program instruction `target` whose instanceof
153-
/// expressions,
154-
/// if any, should be replaced with explicit tests, and the
155-
/// `goto_program` it is part of.
156-
/// \return Side-effect on `target` as above.
155+
/// Replaces expressions like e instanceof A with e.\@class_identifier == "A"
156+
/// or a big-or of similar expressions if we know of subtypes that also satisfy
157+
/// the given test. Does this for the code or guard at a specific instruction.
158+
/// \param goto_program: program to process
159+
/// \param target: instruction to check for instanceof expressions
160+
/// \param inst_switch: set of instructions to switch around once we're done
157161
void remove_instanceoft::lower_instanceof(
158162
goto_programt &goto_program,
159163
goto_programt::targett target,
@@ -167,35 +171,39 @@ void remove_instanceoft::lower_instanceof(
167171
// code (e.g. a guarded-goto), but this assertion checks that this
168172
// assumption is correct and remains true on future evolution of the
169173
// allowable goto instruction types.
170-
assert(!(code_iof && guard_iof));
174+
INVARIANT(
175+
!(code_iof && guard_iof), "instanceof code should not have a guard");
171176
if(code_iof)
172177
lower_instanceof(target->code, goto_program, target, inst_switch);
173178
if(guard_iof)
174179
lower_instanceof(target->guard, goto_program, target, inst_switch);
175180
}
176181

177-
/// See function above
178-
/// \par parameters: `goto_program`, all of whose instanceof expressions will
179-
/// be replaced by explicit class-identifier tests.
180-
/// \return Side-effect on `goto_program` as above.
182+
/// Replace every instanceof in the passed function body with an explicit
183+
/// class-identifier test.
184+
/// Extra auxiliary variables may be introduced into symbol_table.
185+
/// \param goto_program: The function body to work on.
186+
/// \return true if one or more instanceof expressions have been replaced
181187
bool remove_instanceoft::lower_instanceof(goto_programt &goto_program)
182188
{
183189
instanceof_instt inst_switch;
184-
Forall_goto_program_instructions(target, goto_program)
185-
lower_instanceof(goto_program, target, inst_switch);
186-
if(!inst_switch.empty())
190+
for(goto_programt::instructionst::iterator target=
191+
goto_program.instructions.begin();
192+
target!=goto_program.instructions.end();
193+
++target)
187194
{
188-
for(auto &p : inst_switch)
189-
{
190-
const goto_programt::targett &this_inst=p.first;
191-
const goto_programt::targett &newinst=p.second;
192-
this_inst->swap(*newinst);
193-
}
194-
goto_program.update();
195-
return true;
195+
lower_instanceof(goto_program, target, inst_switch);
196196
}
197-
else
197+
if(inst_switch.empty())
198198
return false;
199+
for(auto &p : inst_switch)
200+
{
201+
const goto_programt::targett &this_inst=p.first;
202+
const goto_programt::targett &newinst=p.second;
203+
this_inst->swap(*newinst);
204+
}
205+
goto_program.update();
206+
return true;
199207
}
200208

201209
/// See function above
@@ -226,6 +234,5 @@ void remove_instanceof(
226234

227235
void remove_instanceof(goto_modelt &goto_model)
228236
{
229-
remove_instanceof(
230-
goto_model.symbol_table, goto_model.goto_functions);
237+
remove_instanceof(goto_model.symbol_table, goto_model.goto_functions);
231238
}

0 commit comments

Comments
 (0)