Skip to content

Commit af06d4e

Browse files
authored
Merge pull request diffblue#3216 from smowton/smowton/feature/shared-class-hierarchy
Share a common class_hierarchyt instance across multiple users
2 parents 0e6419e + 5e9aba8 commit af06d4e

File tree

10 files changed

+113
-28
lines changed

10 files changed

+113
-28
lines changed

jbmc/src/janalyzer/janalyzer_parse_options.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -667,13 +667,17 @@ bool janalyzer_parse_optionst::process_goto_program(const optionst &options)
667667
status() << "Removing function pointers and virtual functions" << eom;
668668
remove_function_pointers(
669669
get_message_handler(), goto_model, cmdline.isset("pointer-check"));
670+
670671
// Java virtual functions -> explicit dispatch tables:
671672
remove_virtual_functions(goto_model);
673+
672674
// remove Java throw and catch
673675
// This introduces instanceof, so order is important:
674-
remove_exceptions(goto_model, get_message_handler());
675-
// remove rtti
676-
remove_instanceof(goto_model, get_message_handler());
676+
remove_exceptions(goto_model, nullptr, get_message_handler());
677+
678+
// Java instanceof -> clsid comparison:
679+
class_hierarchyt class_hierarchy(goto_model.symbol_table);
680+
remove_instanceof(goto_model, class_hierarchy, get_message_handler());
677681

678682
// do partial inlining
679683
status() << "Partial Inlining" << eom;

jbmc/src/java_bytecode/remove_exceptions.cpp

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,31 @@ class remove_exceptionst
8787

8888
explicit remove_exceptionst(
8989
symbol_table_baset &_symbol_table,
90+
const class_hierarchyt *class_hierarchy,
9091
function_may_throwt _function_may_throw,
9192
bool remove_added_instanceof,
9293
message_handlert &message_handler)
9394
: symbol_table(_symbol_table),
95+
class_hierarchy(class_hierarchy),
9496
function_may_throw(_function_may_throw),
9597
remove_added_instanceof(remove_added_instanceof),
9698
message_handler(message_handler)
9799
{
100+
if(remove_added_instanceof)
101+
{
102+
INVARIANT(
103+
class_hierarchy != nullptr,
104+
"remove_exceptions needs a class hierarchy to remove instanceof "
105+
"statements (either supply one, or don't use REMOVE_ADDED_INSTANCEOF)");
106+
}
98107
}
99108

100109
void operator()(goto_functionst &goto_functions);
101110
void operator()(goto_programt &goto_program);
102111

103112
protected:
104113
symbol_table_baset &symbol_table;
114+
const class_hierarchyt *class_hierarchy;
105115
function_may_throwt function_may_throw;
106116
bool remove_added_instanceof;
107117
message_handlert &message_handler;
@@ -345,7 +355,14 @@ void remove_exceptionst::add_exception_dispatch_sequence(
345355
t_exc->guard=check;
346356

347357
if(remove_added_instanceof)
348-
remove_instanceof(t_exc, goto_program, symbol_table, message_handler);
358+
{
359+
remove_instanceof(
360+
t_exc,
361+
goto_program,
362+
symbol_table,
363+
*class_hierarchy,
364+
message_handler);
365+
}
349366
}
350367
}
351368
}
@@ -576,6 +593,7 @@ void remove_exceptionst::operator()(goto_programt &goto_program)
576593
/// removes throws/CATCH-POP/CATCH-PUSH
577594
void remove_exceptions(
578595
symbol_table_baset &symbol_table,
596+
const class_hierarchyt *class_hierarchy,
579597
goto_functionst &goto_functions,
580598
message_handlert &message_handler,
581599
remove_exceptions_typest type)
@@ -589,6 +607,7 @@ void remove_exceptions(
589607
};
590608
remove_exceptionst remove_exceptions(
591609
symbol_table,
610+
class_hierarchy,
592611
function_may_throw,
593612
type == remove_exceptions_typest::REMOVE_ADDED_INSTANCEOF,
594613
message_handler);
@@ -605,13 +624,16 @@ void remove_exceptions(
605624
/// \param symbol_table: global symbol table. The `@inflight_exception` global
606625
/// may be added if not already present. It will not be initialised; that is
607626
/// the caller's responsibility.
627+
/// \param class_hierarchy: class hierarchy analysis of symbol_table.
628+
/// Only needed if type == REMOVE_ADDED_INSTANCEOF; otherwise may be null.
608629
/// \param message_handler: logging output
609630
/// \param type: specifies whether instanceof operations generated by this pass
610631
/// should be lowered to class-identifier comparisons (using
611632
/// remove_instanceof).
612633
void remove_exceptions(
613634
goto_programt &goto_program,
614635
symbol_table_baset &symbol_table,
636+
const class_hierarchyt *class_hierarchy,
615637
message_handlert &message_handler,
616638
remove_exceptions_typest type)
617639
{
@@ -620,18 +642,35 @@ void remove_exceptions(
620642

621643
remove_exceptionst remove_exceptions(
622644
symbol_table,
645+
class_hierarchy,
623646
any_function_may_throw,
624647
type == remove_exceptions_typest::REMOVE_ADDED_INSTANCEOF,
625648
message_handler);
626649
remove_exceptions(goto_program);
627650
}
628651

629-
/// removes throws/CATCH-POP/CATCH-PUSH
652+
/// removes throws/CATCH-POP/CATCH-PUSH, replacing them with explicit exception
653+
/// propagation.
654+
/// \param goto_model: model to remove exceptions from. The
655+
/// `@inflight_exception` global may be added to its symbol table if not
656+
/// already present. It will not be initialised; that is the caller's
657+
/// responsibility.
658+
/// \param class_hierarchy: class hierarchy analysis of symbol_table.
659+
/// Only needed if type == REMOVE_ADDED_INSTANCEOF; otherwise may be null.
660+
/// \param message_handler: logging output
661+
/// \param type: specifies whether instanceof operations generated by this pass
662+
/// should be lowered to class-identifier comparisons (using
663+
/// remove_instanceof).
630664
void remove_exceptions(
631665
goto_modelt &goto_model,
666+
const class_hierarchyt *class_hierarchy,
632667
message_handlert &message_handler,
633668
remove_exceptions_typest type)
634669
{
635670
remove_exceptions(
636-
goto_model.symbol_table, goto_model.goto_functions, message_handler, type);
671+
goto_model.symbol_table,
672+
class_hierarchy,
673+
goto_model.goto_functions,
674+
message_handler,
675+
type);
637676
}

jbmc/src/java_bytecode/remove_exceptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Date: December 2016
1414
#ifndef CPROVER_JAVA_BYTECODE_REMOVE_EXCEPTIONS_H
1515
#define CPROVER_JAVA_BYTECODE_REMOVE_EXCEPTIONS_H
1616

17+
#include <goto-programs/class_hierarchy.h>
1718
#include <goto-programs/goto_model.h>
1819

1920
#include <util/message.h>
@@ -34,12 +35,14 @@ enum class remove_exceptions_typest
3435
void remove_exceptions(
3536
goto_programt &goto_program,
3637
symbol_table_baset &symbol_table,
38+
const class_hierarchyt *class_hierarchy,
3739
message_handlert &message_handler,
3840
remove_exceptions_typest type =
3941
remove_exceptions_typest::DONT_REMOVE_INSTANCEOF);
4042

4143
void remove_exceptions(
4244
goto_modelt &goto_model,
45+
const class_hierarchyt *class_hierarchy,
4346
message_handlert &message_handler,
4447
remove_exceptions_typest type =
4548
remove_exceptions_typest::DONT_REMOVE_INSTANCEOF);

jbmc/src/java_bytecode/remove_instanceof.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ class remove_instanceoft
2424
{
2525
public:
2626
remove_instanceoft(
27-
symbol_table_baset &symbol_table, message_handlert &message_handler)
28-
: symbol_table(symbol_table)
29-
, ns(symbol_table)
30-
, message_handler(message_handler)
27+
symbol_table_baset &symbol_table,
28+
const class_hierarchyt &class_hierarchy,
29+
message_handlert &message_handler)
30+
: symbol_table(symbol_table),
31+
class_hierarchy(class_hierarchy),
32+
ns(symbol_table),
33+
message_handler(message_handler)
3134
{
32-
class_hierarchy(symbol_table);
3335
}
3436

3537
// Lower instanceof for a single function
@@ -40,8 +42,8 @@ class remove_instanceoft
4042

4143
protected:
4244
symbol_table_baset &symbol_table;
45+
const class_hierarchyt &class_hierarchy;
4346
namespacet ns;
44-
class_hierarchyt class_hierarchy;
4547
message_handlert &message_handler;
4648

4749
bool lower_instanceof(
@@ -233,21 +235,22 @@ bool remove_instanceoft::lower_instanceof(goto_programt &goto_program)
233235
return true;
234236
}
235237

236-
237238
/// Replace an instanceof in the expression or guard of the passed instruction
238239
/// of the given function body with an explicit class-identifier test.
239240
/// \remarks Extra auxiliary variables may be introduced into symbol_table.
240241
/// \param target: The instruction to work on.
241242
/// \param goto_program: The function body containing the instruction.
242243
/// \param symbol_table: The symbol table to add symbols to.
244+
/// \param class_hierarchy: class hierarchy analysis of symbol_table
243245
/// \param message_handler: logging output
244246
void remove_instanceof(
245247
goto_programt::targett target,
246248
goto_programt &goto_program,
247249
symbol_table_baset &symbol_table,
250+
const class_hierarchyt &class_hierarchy,
248251
message_handlert &message_handler)
249252
{
250-
remove_instanceoft rem(symbol_table, message_handler);
253+
remove_instanceoft rem(symbol_table, class_hierarchy, message_handler);
251254
rem.lower_instanceof(goto_program, target);
252255
}
253256

@@ -256,13 +259,15 @@ void remove_instanceof(
256259
/// \remarks Extra auxiliary variables may be introduced into symbol_table.
257260
/// \param function: The function to work on.
258261
/// \param symbol_table: The symbol table to add symbols to.
262+
/// \param class_hierarchy: class hierarchy analysis of symbol_table
259263
/// \param message_handler: logging output
260264
void remove_instanceof(
261265
goto_functionst::goto_functiont &function,
262266
symbol_table_baset &symbol_table,
267+
const class_hierarchyt &class_hierarchy,
263268
message_handlert &message_handler)
264269
{
265-
remove_instanceoft rem(symbol_table, message_handler);
270+
remove_instanceoft rem(symbol_table, class_hierarchy, message_handler);
266271
rem.lower_instanceof(function.body);
267272
}
268273

@@ -271,13 +276,15 @@ void remove_instanceof(
271276
/// \remarks Extra auxiliary variables may be introduced into symbol_table.
272277
/// \param goto_functions: The functions to work on.
273278
/// \param symbol_table: The symbol table to add symbols to.
279+
/// \param class_hierarchy: class hierarchy analysis of symbol_table
274280
/// \param message_handler: logging output
275281
void remove_instanceof(
276282
goto_functionst &goto_functions,
277283
symbol_table_baset &symbol_table,
284+
const class_hierarchyt &class_hierarchy,
278285
message_handlert &message_handler)
279286
{
280-
remove_instanceoft rem(symbol_table, message_handler);
287+
remove_instanceoft rem(symbol_table, class_hierarchy, message_handler);
281288
bool changed=false;
282289
for(auto &f : goto_functions.function_map)
283290
changed=rem.lower_instanceof(f.second.body) || changed;
@@ -289,12 +296,18 @@ void remove_instanceof(
289296
/// class-identifier test.
290297
/// \remarks Extra auxiliary variables may be introduced into symbol_table.
291298
/// \param goto_model: The functions to work on and the symbol table to add
299+
/// \param class_hierarchy: class hierarchy analysis of goto_model's symbol
300+
/// table
292301
/// \param message_handler: logging output
293302
/// symbols to.
294303
void remove_instanceof(
295304
goto_modelt &goto_model,
305+
const class_hierarchyt &class_hierarchy,
296306
message_handlert &message_handler)
297307
{
298308
remove_instanceof(
299-
goto_model.goto_functions, goto_model.symbol_table, message_handler);
309+
goto_model.goto_functions,
310+
goto_model.symbol_table,
311+
class_hierarchy,
312+
message_handler);
300313
}

jbmc/src/java_bytecode/remove_instanceof.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ Author: Chris Smowton, [email protected]
7979
#ifndef CPROVER_JAVA_BYTECODE_REMOVE_INSTANCEOF_H
8080
#define CPROVER_JAVA_BYTECODE_REMOVE_INSTANCEOF_H
8181

82+
#include <goto-programs/class_hierarchy.h>
8283
#include <goto-programs/goto_functions.h>
8384
#include <goto-programs/goto_model.h>
8485

@@ -89,18 +90,24 @@ void remove_instanceof(
8990
goto_programt::targett target,
9091
goto_programt &goto_program,
9192
symbol_table_baset &symbol_table,
93+
const class_hierarchyt &class_hierarchy,
9294
message_handlert &);
9395

9496
void remove_instanceof(
9597
goto_functionst::goto_functiont &function,
9698
symbol_table_baset &symbol_table,
99+
const class_hierarchyt &class_hierarchy,
97100
message_handlert &);
98101

99102
void remove_instanceof(
100103
goto_functionst &goto_functions,
101104
symbol_table_baset &symbol_table,
105+
const class_hierarchyt &class_hierarchy,
102106
message_handlert &);
103107

104-
void remove_instanceof(goto_modelt &model, message_handlert &);
108+
void remove_instanceof(
109+
goto_modelt &model,
110+
const class_hierarchyt &class_hierarchy,
111+
message_handlert &);
105112

106113
#endif

jbmc/src/jbmc/jbmc_parse_options.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,9 @@ int jbmc_parse_optionst::doit()
552552
*this, options, get_message_handler());
553553
lazy_goto_model.initialize(cmdline, options);
554554

555+
class_hierarchy =
556+
util_make_unique<class_hierarchyt>(lazy_goto_model.symbol_table);
557+
555558
// The precise wording of this error matches goto-symex's complaint when no
556559
// __CPROVER_start exists (if we just go ahead and run it anyway it will
557560
// trip an invariant when it tries to load it)
@@ -629,12 +632,13 @@ int jbmc_parse_optionst::get_goto_program(
629632
*this, options, get_message_handler());
630633
lazy_goto_model.initialize(cmdline, options);
631634

635+
class_hierarchy =
636+
util_make_unique<class_hierarchyt>(lazy_goto_model.symbol_table);
637+
632638
// Show the class hierarchy
633639
if(cmdline.isset("show-class-hierarchy"))
634640
{
635-
class_hierarchyt hierarchy;
636-
hierarchy(lazy_goto_model.symbol_table);
637-
show_class_hierarchy(hierarchy, ui_message_handler);
641+
show_class_hierarchy(*class_hierarchy, ui_message_handler);
638642
return CPROVER_EXIT_SUCCESS;
639643
}
640644

@@ -729,7 +733,8 @@ void jbmc_parse_optionst::process_goto_function(
729733
try
730734
{
731735
// Removal of RTTI inspection:
732-
remove_instanceof(goto_function, symbol_table, get_message_handler());
736+
remove_instanceof(
737+
goto_function, symbol_table, *class_hierarchy, get_message_handler());
733738
// Java virtual functions -> explicit dispatch tables:
734739
remove_virtual_functions(function);
735740

@@ -743,6 +748,7 @@ void jbmc_parse_optionst::process_goto_function(
743748
remove_exceptions(
744749
goto_function.body,
745750
symbol_table,
751+
class_hierarchy.get(),
746752
get_message_handler(),
747753
remove_exceptions_typest::REMOVE_ADDED_INSTANCEOF);
748754
}
@@ -888,6 +894,7 @@ bool jbmc_parse_optionst::process_goto_functions(
888894
// (introduces instanceof but request it is removed)
889895
remove_exceptions(
890896
goto_model,
897+
class_hierarchy.get(),
891898
get_message_handler(),
892899
remove_exceptions_typest::REMOVE_ADDED_INSTANCEOF);
893900

jbmc/src/jbmc/jbmc_parse_options.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ class jbmc_parse_optionst:
123123
object_factory_parameterst object_factory_params;
124124
bool stub_objects_are_not_null;
125125

126+
std::unique_ptr<class_hierarchyt> class_hierarchy;
127+
126128
void get_command_line_options(optionst &);
127129
int get_goto_program(
128130
std::unique_ptr<goto_modelt> &goto_model, const optionst &);

jbmc/src/jdiff/jdiff_parse_options.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -345,16 +345,20 @@ bool jdiff_parse_optionst::process_goto_program(
345345
try
346346
{
347347
// remove function pointers
348-
status() << "Removal of function pointers and virtual functions" << eom;
348+
status() << "Removing function pointers and virtual functions" << eom;
349349
remove_function_pointers(
350350
get_message_handler(), goto_model, cmdline.isset("pointer-check"));
351351

352352
// Java virtual functions -> explicit dispatch tables:
353353
remove_virtual_functions(goto_model);
354-
// remove catch and throw
355-
remove_exceptions(goto_model, get_message_handler());
354+
355+
// remove Java throw and catch
356+
// This introduces instanceof, so order is important:
357+
remove_exceptions(goto_model, nullptr, get_message_handler());
358+
356359
// Java instanceof -> clsid comparison:
357-
remove_instanceof(goto_model, get_message_handler());
360+
class_hierarchyt class_hierarchy(goto_model.symbol_table);
361+
remove_instanceof(goto_model, class_hierarchy, get_message_handler());
358362

359363
mm_io(goto_model);
360364

0 commit comments

Comments
 (0)