Skip to content

Commit 47cd927

Browse files
Ignore AssertionError
This is ignored when we comoute the set of escaped exceptions as well as when replacing throws.
1 parent f59ec9a commit 47cd927

File tree

3 files changed

+66
-18
lines changed

3 files changed

+66
-18
lines changed

src/analyses/uncaught_exceptions_analysis.cpp

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,11 @@ Function: get_static_type
8383
8484
Outputs:
8585
86-
Purpose:
86+
Purpose: Returns the compile type of an exception
8787
8888
\*******************************************************************/
8989

90-
static irep_idt get_static_type(const typet &type)
90+
irep_idt uncaught_exceptions_domaint::get_static_type(const typet &type)
9191
{
9292
if(type.id()==ID_pointer)
9393
{
@@ -102,6 +102,26 @@ static irep_idt get_static_type(const typet &type)
102102

103103
/*******************************************************************\
104104
105+
Function: get_exception_symbol
106+
107+
Inputs:
108+
109+
Outputs:
110+
111+
Purpose: Returns the symbol corresponding to an exception
112+
113+
\*******************************************************************/
114+
115+
exprt uncaught_exceptions_domaint::get_exception_symbol(const exprt &expr)
116+
{
117+
if(expr.id()!=ID_symbol && expr.has_operands())
118+
return get_exception_symbol(expr.op0());
119+
120+
return expr;
121+
}
122+
123+
/*******************************************************************\
124+
105125
Function: uncaught_exceptions_domaint::join
106126
107127
Inputs:
@@ -148,16 +168,20 @@ void uncaught_exceptions_domaint::transform(
148168
{
149169
case THROW:
150170
{
151-
const exprt &exc_symbol=instruction.code;
152-
171+
const exprt &exc_symbol=get_exception_symbol(instruction.code);
153172
// retrieve the static type of the thrown exception
154173
const irep_idt &type_id=get_static_type(exc_symbol.type());
155-
join(type_id);
156-
// we must consider all the subtypes given that
157-
// the runtime type is a subtype of the static type
158-
std::set<irep_idt> subtypes;
159-
get_subtypes(type_id, subtypes, ns);
160-
join(subtypes);
174+
bool assertion_error=
175+
id2string(type_id).find("java.lang.AssertionError")!=std::string::npos;
176+
if(!assertion_error)
177+
{
178+
join(type_id);
179+
// we must consider all the subtypes given that
180+
// the runtime type is a subtype of the static type
181+
std::set<irep_idt> subtypes;
182+
get_subtypes(type_id, subtypes, ns);
183+
join(subtypes);
184+
}
161185
break;
162186
}
163187
case CATCH:

src/analyses/uncaught_exceptions_analysis.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ class uncaught_exceptions_domaint
4141
stack_caught.clear();
4242
}
4343

44+
static irep_idt get_static_type(const typet &type);
45+
46+
static exprt get_exception_symbol(const exprt &exor);
47+
4448
void get_elements(std::set<irep_idt> &elements);
4549

4650
private:

src/goto-programs/remove_exceptions.cpp

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,8 @@ void remove_exceptionst::add_exceptional_returns(
115115
return;
116116
}
117117

118-
// We generate an exceptional return value for any function that has
119-
// a throw or a function call. This can be improved by only considering
120-
// function calls that may escape exceptions. However, this will
121-
// require multiple passes.
118+
// We generate an exceptional return value for any function that
119+
// contains a throw or a function call that may escape exceptions.
122120
bool add_exceptional_var=false;
123121
bool has_uncaught_exceptions=false;
124122
forall_goto_program_instructions(instr_it, goto_program)
@@ -133,7 +131,17 @@ void remove_exceptionst::add_exceptional_returns(
133131
has_uncaught_exceptions=!exceptions_map[function_name].empty();
134132
}
135133

136-
if(instr_it->is_throw() || has_uncaught_exceptions)
134+
const exprt &exc =
135+
uncaught_exceptions_domaint::get_exception_symbol(instr_it->code);
136+
bool assertion_error =
137+
id2string(uncaught_exceptions_domaint::get_static_type(exc.type())).
138+
find("java.lang.AssertionError")!=std::string::npos;
139+
140+
// if we find a throw that is not AssertionError of a function call
141+
// that may escape exceptions, then we add an exceptional return
142+
// variable
143+
if((instr_it->is_throw() && !assertion_error)
144+
|| has_uncaught_exceptions)
137145
{
138146
add_exceptional_var=true;
139147
break;
@@ -282,6 +290,18 @@ void remove_exceptionst::instrument_throw(
282290
{
283291
assert(instr_it->type==THROW);
284292

293+
const exprt &exc_expr=
294+
uncaught_exceptions_domaint::get_exception_symbol(instr_it->code);
295+
bool assertion_error=id2string(
296+
uncaught_exceptions_domaint::get_static_type(exc_expr.type())).
297+
find("java.lang.AssertionError")!=std::string::npos;
298+
299+
// we don't count AssertionError (we couldn't catch it anyway
300+
// and this may reduce the instrumentation considerably if the programmer
301+
// used assertions)
302+
if(assertion_error)
303+
return;
304+
285305
goto_programt &goto_program=func_it->second.body;
286306
const irep_idt &function_id=func_it->first;
287307

@@ -341,9 +361,9 @@ void remove_exceptionst::instrument_throw(
341361
}
342362

343363
// replace "throw x;" by "f#exception_value=x;"
344-
exprt exc_expr=instr_it->code;
345-
while(exc_expr.id()!=ID_symbol && exc_expr.has_operands())
346-
exc_expr=exc_expr.op0();
364+
// exprt exc_expr=instr_it->code;
365+
// while(exc_expr.id()!=ID_symbol && exc_expr.has_operands())
366+
// exc_expr=exc_expr.op0();
347367

348368
// add the assignment with the appropriate cast
349369
code_assignt assignment(typecast_exprt(exc_thrown, exc_expr.type()),

0 commit comments

Comments
 (0)