Skip to content

Commit 7707287

Browse files
Always push the current exceptional return variable on the stack before converting an exception handler
1 parent a54d806 commit 7707287

File tree

3 files changed

+42
-48
lines changed

3 files changed

+42
-48
lines changed

src/goto-programs/remove_exceptions.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ void remove_exceptionst::add_exceptional_returns(
9090
if(goto_program.empty())
9191
return;
9292

93-
// the entry function has already been added to the symbol table
94-
// if you find it, initialise it
93+
// some methods (e.g. the entry method) have already been added to
94+
// the symbol table; if you find it, initialise it
9595
if(symbol_table.has_symbol(id2string(function_id)+EXC_SUFFIX))
9696
{
9797
const symbolt &symbol=

src/java_bytecode/java_bytecode_convert_method.cpp

+29-38
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"
@@ -1305,48 +1306,37 @@ codet java_bytecode_convert_methodt::convert_instructions(
13051306
statement=std::string(id2string(statement), 0, statement.size()-2);
13061307
}
13071308

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

1344-
if(it!=method.exception_table.end())
1345-
{
1346-
// go straight to the next statement
1347-
continue;
1348-
}
1349-
13501340
exprt::operandst op=pop(bytecode_info.pop);
13511341
exprt::operandst results;
13521342
results.resize(bytecode_info.push, nil_exprt());
@@ -2407,6 +2397,10 @@ codet java_bytecode_convert_methodt::convert_instructions(
24072397
results[1]=op[0];
24082398
results[0]=op[1];
24092399
}
2400+
else if(statement=="nop")
2401+
{
2402+
c=code_skipt();
2403+
}
24102404
else
24112405
{
24122406
c=codet(statement);
@@ -2533,9 +2527,7 @@ codet java_bytecode_convert_methodt::convert_instructions(
25332527
address_mapt::iterator a_it2=address_map.find(address);
25342528
assert(a_it2!=address_map.end());
25352529

2536-
// we don't worry about exception handlers as we don't load the
2537-
// operands from the stack anyway -- we keep explicit global
2538-
// exception variables
2530+
// clear the stack if this is an exception handler
25392531
for(const auto &exception_row : method.exception_table)
25402532
{
25412533
if(address==exception_row.handler_pc)
@@ -2604,7 +2596,6 @@ codet java_bytecode_convert_methodt::convert_instructions(
26042596
c.copy_to_operands(*o_it);
26052597
}
26062598
}
2607-
26082599
a_it2->second.stack=stack;
26092600
}
26102601
}

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=false;
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)