@@ -79,23 +79,25 @@ class remove_exceptionst
79
79
typedef std::vector<std::pair<
80
80
irep_idt, goto_programt::targett>> catch_handlerst;
81
81
typedef std::vector<catch_handlerst> stack_catcht;
82
+ typedef std::function<bool (const irep_idt &)> function_may_throwt;
82
83
83
84
public:
84
85
explicit remove_exceptionst (
85
- symbol_tablet &_symbol_table,
86
- std::map<irep_idt, std::set<irep_idt>> &_exceptions_map ,
86
+ symbol_table_baset &_symbol_table,
87
+ function_may_throwt _function_may_throw ,
87
88
bool remove_added_instanceof)
88
89
: symbol_table(_symbol_table),
89
- exceptions_map(_exceptions_map ),
90
+ function_may_throw(_function_may_throw ),
90
91
remove_added_instanceof(remove_added_instanceof)
91
92
{
92
93
}
93
94
94
95
void operator ()(goto_functionst &goto_functions);
96
+ void operator ()(goto_programt &goto_program);
95
97
96
98
protected:
97
- symbol_tablet &symbol_table;
98
- std::map<irep_idt, std::set<irep_idt>> &exceptions_map ;
99
+ symbol_table_baset &symbol_table;
100
+ function_may_throwt function_may_throw ;
99
101
bool remove_added_instanceof;
100
102
101
103
symbol_exprt get_inflight_exception_global ();
@@ -177,8 +179,7 @@ bool remove_exceptionst::function_or_callees_may_throw(
177
179
" identifier expected to be a symbol" );
178
180
const irep_idt &function_name=
179
181
to_symbol_expr (function_expr).get_identifier ();
180
- bool callee_may_throw = !exceptions_map[function_name].empty ();
181
- if (callee_may_throw)
182
+ if (function_may_throw (function_name))
182
183
return true ;
183
184
}
184
185
}
@@ -424,9 +425,7 @@ void remove_exceptionst::instrument_function_call(
424
425
const irep_idt &callee_id=
425
426
to_symbol_expr (function_call.function ()).get_identifier ();
426
427
427
- bool callee_may_throw = !exceptions_map[callee_id].empty ();
428
-
429
- if (callee_may_throw)
428
+ if (function_may_throw (callee_id))
430
429
{
431
430
add_exception_dispatch_sequence (
432
431
goto_program, instr_it, stack_catch, locals);
@@ -557,22 +556,58 @@ void remove_exceptionst::operator()(goto_functionst &goto_functions)
557
556
instrument_exceptions (it->second .body );
558
557
}
559
558
559
+ void remove_exceptionst::operator ()(goto_programt &goto_program)
560
+ {
561
+ instrument_exceptions (goto_program);
562
+ }
563
+
560
564
// / removes throws/CATCH-POP/CATCH-PUSH
561
565
void remove_exceptions (
562
- symbol_tablet &symbol_table,
566
+ symbol_table_baset &symbol_table,
563
567
goto_functionst &goto_functions,
564
568
remove_exceptions_typest type)
565
569
{
566
570
const namespacet ns (symbol_table);
567
571
std::map<irep_idt, std::set<irep_idt>> exceptions_map;
568
572
uncaught_exceptions (goto_functions, ns, exceptions_map);
573
+ // NOLINTNEXTLINE
574
+ auto function_may_throw = [&exceptions_map](const irep_idt &id) {
575
+ return !exceptions_map[id].empty ();
576
+ };
569
577
remove_exceptionst remove_exceptions (
570
578
symbol_table,
571
- exceptions_map ,
579
+ function_may_throw ,
572
580
type == remove_exceptions_typest::REMOVE_ADDED_INSTANCEOF);
573
581
remove_exceptions (goto_functions);
574
582
}
575
583
584
+ // / removes throws/CATCH-POP/CATCH-PUSH from a single GOTO program, replacing
585
+ // / them with explicit exception propagation.
586
+ // / Note this is somewhat less accurate than the whole-goto-model version,
587
+ // / because we can't inspect other functions to determine whether they throw
588
+ // / or not, and therefore must assume they do and always introduce post-call
589
+ // / exception dispatch.
590
+ // / \param goto_program: program to remove exceptions from
591
+ // / \param symbol_table: global symbol table. The `@inflight_exception` global
592
+ // / may be added if not already present. It will not be initialised; that is
593
+ // / the caller's responsibility.
594
+ // / \param type: specifies whether instanceof operations generated by this pass
595
+ // / should be lowered to class-identifier comparisons (using
596
+ // / remove_instanceof).
597
+ void remove_exceptions (
598
+ goto_programt &goto_program,
599
+ symbol_table_baset &symbol_table,
600
+ remove_exceptions_typest type)
601
+ {
602
+ auto any_function_may_throw = [](const irep_idt &id) { return true ; };
603
+
604
+ remove_exceptionst remove_exceptions (
605
+ symbol_table,
606
+ any_function_may_throw,
607
+ type == remove_exceptions_typest::REMOVE_ADDED_INSTANCEOF);
608
+ remove_exceptions (goto_program);
609
+ }
610
+
576
611
// / removes throws/CATCH-POP/CATCH-PUSH
577
612
void remove_exceptions (goto_modelt &goto_model, remove_exceptions_typest type)
578
613
{
0 commit comments