@@ -30,6 +30,8 @@ Date: December 2016
30
30
31
31
#include < analyses/uncaught_exceptions_analysis.h>
32
32
33
+ #include < linking/static_lifetime_init.h>
34
+
33
35
#include " java_types.h"
34
36
35
37
// / Lowers high-level exception descriptions into low-level operations suitable
@@ -119,6 +121,13 @@ class remove_exceptionst
119
121
bool remove_added_instanceof;
120
122
message_handlert &message_handler;
121
123
124
+ enum class instrumentation_resultt
125
+ {
126
+ DID_NOTHING,
127
+ ADDED_CODE_WITHOUT_MAY_THROW,
128
+ ADDED_CODE_WITH_MAY_THROW,
129
+ };
130
+
122
131
symbol_exprt get_inflight_exception_global ();
123
132
124
133
bool function_or_callees_may_throw (const goto_programt &) const ;
@@ -148,7 +157,7 @@ class remove_exceptionst
148
157
const stack_catcht &,
149
158
const std::vector<symbol_exprt> &);
150
159
151
- bool instrument_function_call (
160
+ instrumentation_resultt instrument_function_call (
152
161
const irep_idt &function_identifier,
153
162
goto_programt &goto_program,
154
163
const goto_programt::targett &,
@@ -207,7 +216,7 @@ bool remove_exceptionst::function_or_callees_may_throw(
207
216
// / Translates an exception landing-pad into instructions that copy the
208
217
// / in-flight exception pointer to a nominated expression, then clear the
209
218
// / in-flight exception (i.e. null the pointer), hence marking it caught.
210
- // / \param goto_program: body of the function containing this landingpad
219
+ // / \param [out] goto_program: body of the function containing this landingpad
211
220
// / instruction
212
221
// / \param instr_it: iterator pointing to the landingpad instruction.
213
222
// / Will be overwritten.
@@ -421,7 +430,8 @@ bool remove_exceptionst::instrument_throw(
421
430
422
431
// / instruments each function call that may escape exceptions with conditional
423
432
// / GOTOS to the corresponding exception handlers
424
- bool remove_exceptionst::instrument_function_call (
433
+ remove_exceptionst::instrumentation_resultt
434
+ remove_exceptionst::instrument_function_call (
425
435
const irep_idt &function_identifier,
426
436
goto_programt &goto_program,
427
437
const goto_programt::targett &instr_it,
@@ -455,6 +465,8 @@ bool remove_exceptionst::instrument_function_call(
455
465
goto_program.insert_after (
456
466
instr_it,
457
467
goto_programt::make_assumption (no_exception_currently_in_flight));
468
+
469
+ return instrumentation_resultt::ADDED_CODE_WITHOUT_MAY_THROW;
458
470
}
459
471
else
460
472
{
@@ -468,12 +480,12 @@ bool remove_exceptionst::instrument_function_call(
468
480
next_it,
469
481
no_exception_currently_in_flight,
470
482
instr_it->source_location ));
471
- }
472
483
473
- return true ;
484
+ return instrumentation_resultt::ADDED_CODE_WITH_MAY_THROW;
485
+ }
474
486
}
475
487
476
- return false ;
488
+ return instrumentation_resultt::DID_NOTHING ;
477
489
}
478
490
479
491
// / instruments throws, function calls that may escape exceptions and exception
@@ -494,6 +506,7 @@ void remove_exceptionst::instrument_exceptions(
494
506
function_or_callees_may_throw (goto_program);
495
507
496
508
bool did_something = false ;
509
+ bool added_goto_instruction = false ;
497
510
498
511
Forall_goto_program_instructions (instr_it, goto_program)
499
512
{
@@ -577,16 +590,29 @@ void remove_exceptionst::instrument_exceptions(
577
590
}
578
591
else if (instr_it->type ==THROW)
579
592
{
580
- did_something | = instrument_throw (
593
+ did_something = instrument_throw (
581
594
function_identifier, goto_program, instr_it, stack_catch, locals);
582
595
}
583
596
else if (instr_it->type ==FUNCTION_CALL)
584
597
{
585
- did_something |= instrument_function_call (
586
- function_identifier, goto_program, instr_it, stack_catch, locals);
598
+ instrumentation_resultt result =
599
+ instrument_function_call (
600
+ function_identifier, goto_program, instr_it, stack_catch, locals);
601
+ did_something = result != instrumentation_resultt::DID_NOTHING;
602
+ added_goto_instruction =
603
+ result == instrumentation_resultt::ADDED_CODE_WITH_MAY_THROW;
587
604
}
588
605
}
589
606
607
+ // INITIALIZE_FUNCTION should not contain any exception handling branches for
608
+ // two reasons: (1) with symex-driven lazy loading it means that code that
609
+ // references @inflight_exception might be generated before
610
+ // @inflight_exception is initialized; (2) symex can analyze
611
+ // INITIALIZE_FUNCTION much faster if it doesn't contain any branching.
612
+ INVARIANT (
613
+ function_identifier != INITIALIZE_FUNCTION || !added_goto_instruction,
614
+ INITIALIZE_FUNCTION " should not contain any exception handling branches" );
615
+
590
616
if (did_something)
591
617
remove_skip (goto_program);
592
618
}
0 commit comments