Skip to content

Commit a308fb5

Browse files
authored
Merge pull request #996 from cristina-david/bug/remove-assumptions-about-exception-handlers
Remove assumptions about exception handlers
2 parents 4b9f42e + 8f629b6 commit a308fb5

File tree

7 files changed

+69
-51
lines changed

7 files changed

+69
-51
lines changed
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
.class exception_handler
2+
.super java/lang/Object
3+
4+
.method public <init>()V
5+
aload_0
6+
invokevirtual java/lang/Object/<init>()V
7+
return
8+
.end method
9+
10+
.method public f()V
11+
.limit stack 4
12+
.limit locals 4
13+
14+
begin:
15+
new java/lang/Exception
16+
dup
17+
invokespecial java/lang/Exception.<init>()V
18+
athrow
19+
start:
20+
dup
21+
end:
22+
astore_1
23+
return
24+
.catch all from begin to end using start
25+
.end method
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
exception_handler.class
3+
--function exception_handler.f
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
^warning: ignoring

src/goto-programs/remove_exceptions.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ void remove_exceptionst::add_exceptional_returns(
9595
if(goto_program.empty())
9696
return;
9797

98-
// the entry function has already been added to the symbol table
99-
// if you find it, initialise it
98+
// some methods (e.g. the entry method) have already been added to
99+
// the symbol table; if you find it, initialise it
100100
if(symbol_table.has_symbol(id2string(function_id)+EXC_SUFFIX))
101101
{
102102
const symbolt &symbol=

src/java_bytecode/java_bytecode_convert_method.cpp

+21-40
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Author: Daniel Kroening, [email protected]
2020
#include <linking/zero_initializer.h>
2121

2222
#include <goto-programs/cfg.h>
23+
#include <goto-programs/remove_exceptions.h>
2324
#include <analyses/cfg_dominators.h>
2425

2526
#include "java_bytecode_convert_method.h"
@@ -473,7 +474,8 @@ void java_bytecode_convert_methodt::convert(
473474

474475
tmp_vars.clear();
475476
if((!m.is_abstract) && (!m.is_native))
476-
method_symbol.value=convert_instructions(m, code_type);
477+
method_symbol.value=convert_instructions(
478+
m, code_type, method_symbol.name);
477479

478480
// Replace the existing stub symbol with the real deal:
479481
const auto s_it=symbol_table.symbols.find(method.get_name());
@@ -1120,7 +1122,8 @@ Function: java_bytecode_convert_methodt::convert_instructions
11201122

11211123
codet java_bytecode_convert_methodt::convert_instructions(
11221124
const methodt &method,
1123-
const code_typet &method_type)
1125+
const code_typet &method_type,
1126+
const irep_idt &method_name)
11241127
{
11251128
const instructionst &instructions=method.instructions;
11261129

@@ -1306,48 +1309,29 @@ codet java_bytecode_convert_methodt::convert_instructions(
13061309
statement=std::string(id2string(statement), 0, statement.size()-2);
13071310
}
13081311

1309-
// we throw away the first statement in an exception handler
1310-
// as we don't know if a function call had a normal or exceptional return
13111312
auto it=method.exception_table.begin();
13121313
for(; it!=method.exception_table.end(); ++it)
13131314
{
13141315
if(cur_pc==it->handler_pc)
13151316
{
1316-
exprt exc_var=variable(
1317-
arg0, statement[0],
1318-
i_it->address,
1319-
NO_CAST);
1320-
1321-
// throw away the operands
1322-
pop_residue(bytecode_info.pop);
1323-
1324-
// add a CATCH-PUSH signaling a handler
1325-
side_effect_expr_catcht catch_handler_expr;
1326-
// pack the exception variable so that it can be used
1327-
// later for instrumentation
1328-
catch_handler_expr.get_sub().resize(1);
1329-
catch_handler_expr.get_sub()[0]=exc_var;
1330-
1331-
code_expressiont catch_handler(catch_handler_expr);
1332-
code_labelt newlabel(label(std::to_string(cur_pc)),
1333-
code_blockt());
1334-
1335-
code_blockt label_block=to_code_block(newlabel.code());
1336-
code_blockt handler_block;
1337-
handler_block.move_to_operands(c);
1338-
handler_block.move_to_operands(catch_handler);
1339-
handler_block.move_to_operands(label_block);
1340-
c=handler_block;
1341-
break;
1317+
// at the beginning of a handler, clear the stack and
1318+
// push the corresponding exceptional return variable
1319+
stack.clear();
1320+
auxiliary_symbolt new_symbol;
1321+
new_symbol.is_static_lifetime=true;
1322+
// generate the name of the exceptional return variable
1323+
const std::string &exceptional_var_name=
1324+
id2string(method_name)+
1325+
EXC_SUFFIX;
1326+
new_symbol.base_name=exceptional_var_name;
1327+
new_symbol.name=exceptional_var_name;
1328+
new_symbol.type=typet(ID_pointer, empty_typet());
1329+
new_symbol.mode=ID_java;
1330+
symbol_table.add(new_symbol);
1331+
stack.push_back(new_symbol.symbol_expr());
13421332
}
13431333
}
13441334

1345-
if(it!=method.exception_table.end())
1346-
{
1347-
// go straight to the next statement
1348-
continue;
1349-
}
1350-
13511335
exprt::operandst op=pop(bytecode_info.pop);
13521336
exprt::operandst results;
13531337
results.resize(bytecode_info.push, nil_exprt());
@@ -2536,9 +2520,7 @@ codet java_bytecode_convert_methodt::convert_instructions(
25362520
address_mapt::iterator a_it2=address_map.find(address);
25372521
assert(a_it2!=address_map.end());
25382522

2539-
// we don't worry about exception handlers as we don't load the
2540-
// operands from the stack anyway -- we keep explicit global
2541-
// exception variables
2523+
// clear the stack if this is an exception handler
25422524
for(const auto &exception_row : method.exception_table)
25432525
{
25442526
if(address==exception_row.handler_pc)
@@ -2607,7 +2589,6 @@ codet java_bytecode_convert_methodt::convert_instructions(
26072589
c.copy_to_operands(*o_it);
26082590
}
26092591
}
2610-
26112592
a_it2->second.stack=stack;
26122593
}
26132594
}

src/java_bytecode/java_bytecode_convert_method_class.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ class java_bytecode_convert_methodt:public messaget
217217

218218
codet convert_instructions(
219219
const methodt &,
220-
const code_typet &);
220+
const code_typet &,
221+
const irep_idt &);
221222

222223
const bytecode_infot &get_bytecode_info(const irep_idt &statement);
223224

src/java_bytecode/java_entry_point.cpp

+11-8
Original file line numberDiff line numberDiff line change
@@ -589,14 +589,17 @@ bool java_entry_point(
589589
call_main.lhs()=return_symbol.symbol_expr();
590590
}
591591

592-
// add the exceptional return value
593-
auxiliary_symbolt exc_symbol;
594-
exc_symbol.mode=ID_C;
595-
exc_symbol.is_static_lifetime=false;
596-
exc_symbol.name=id2string(symbol.name)+EXC_SUFFIX;
597-
exc_symbol.base_name=id2string(symbol.name)+EXC_SUFFIX;
598-
exc_symbol.type=typet(ID_pointer, empty_typet());
599-
symbol_table.add(exc_symbol);
592+
if(!symbol_table.has_symbol(id2string(symbol.name)+EXC_SUFFIX))
593+
{
594+
// add the exceptional return value
595+
auxiliary_symbolt exc_symbol;
596+
exc_symbol.mode=ID_C;
597+
exc_symbol.is_static_lifetime=true;
598+
exc_symbol.name=id2string(symbol.name)+EXC_SUFFIX;
599+
exc_symbol.base_name=id2string(symbol.name)+EXC_SUFFIX;
600+
exc_symbol.type=typet(ID_pointer, empty_typet());
601+
symbol_table.add(exc_symbol);
602+
}
600603

601604
exprt::operandst main_arguments=
602605
java_build_arguments(

0 commit comments

Comments
 (0)