Skip to content

Commit 1a3eb1c

Browse files
authored
Merge pull request #945 from romainbrenguier/feature/object-get-class
Code for Object.getClass in bytecode conversion
2 parents 3d80c6f + db1cd5f commit 1a3eb1c

File tree

3 files changed

+104
-46
lines changed

3 files changed

+104
-46
lines changed

src/java_bytecode/java_string_library_preprocess.cpp

+95
Original file line numberDiff line numberDiff line change
@@ -1723,6 +1723,93 @@ codet java_string_library_preprocesst::make_string_to_char_array_code(
17231723

17241724
/*******************************************************************\
17251725
1726+
Function: java_string_library_preprocesst::make_object_get_class_code
1727+
1728+
Inputs:
1729+
type - type of the function called
1730+
loc - location in the source
1731+
symbol_table - the symbol table
1732+
1733+
Outputs: Code corresponding to
1734+
> Class class1;
1735+
> string_expr1 = substr(this->@class_identifier, 6)
1736+
> class1=Class.forName(string_expr1)
1737+
> return class1
1738+
1739+
Purpose: Used to provide our own implementation of the
1740+
java.lang.Object.getClass() function.
1741+
1742+
\*******************************************************************/
1743+
1744+
codet java_string_library_preprocesst::make_object_get_class_code(
1745+
const code_typet &type,
1746+
const source_locationt &loc,
1747+
symbol_tablet &symbol_table)
1748+
{
1749+
code_typet::parameterst params=type.parameters();
1750+
exprt this_obj=symbol_exprt(params[0].get_identifier(), params[0].type());
1751+
1752+
// Code to be returned
1753+
code_blockt code;
1754+
1755+
// > Class class1;
1756+
pointer_typet class_type(symbol_table.lookup("java::java.lang.Class").type);
1757+
symbolt class1_sym=get_fresh_aux_symbol(
1758+
class_type, "class_symbol", "class_symbol", loc, ID_java, symbol_table);
1759+
symbol_exprt class1=class1_sym.symbol_expr();
1760+
code.add(code_declt(class1));
1761+
1762+
// class_identifier is this->@class_identifier
1763+
member_exprt class_identifier(
1764+
dereference_exprt(this_obj, this_obj.type().subtype()),
1765+
"@class_identifier",
1766+
string_typet());
1767+
1768+
// string_expr = cprover_string_literal(this->@class_identifier)
1769+
string_exprt string_expr=fresh_string_expr(loc, symbol_table, code);
1770+
code.add(
1771+
code_assign_function_to_string_expr(
1772+
string_expr,
1773+
ID_cprover_string_literal_func,
1774+
{class_identifier},
1775+
symbol_table));
1776+
1777+
// string_expr1 = substr(string_expr, 6)
1778+
// We do this to remove the "java::" prefix
1779+
string_exprt string_expr1=fresh_string_expr(loc, symbol_table, code);
1780+
code.add(
1781+
code_assign_function_to_string_expr(
1782+
string_expr1,
1783+
ID_cprover_string_substring_func,
1784+
{string_expr, from_integer(6, java_int_type())},
1785+
symbol_table));
1786+
1787+
// string1 = (String*) string_expr
1788+
pointer_typet string_ptr_type(
1789+
symbol_table.lookup("java::java.lang.String").type);
1790+
exprt string1=allocate_fresh_string(string_ptr_type, loc, symbol_table, code);
1791+
code.add(
1792+
code_assign_string_expr_to_new_java_string(
1793+
string1, string_expr1, loc, symbol_table));
1794+
1795+
// > class1 = Class.forName(string1)
1796+
code_function_callt fun_call;
1797+
fun_call.function()=symbol_exprt(
1798+
"java::java.lang.Class.forName:(Ljava/lang/String;)Ljava/lang/Class;");
1799+
fun_call.lhs()=class1;
1800+
fun_call.arguments().push_back(string1);
1801+
code_typet fun_type;
1802+
fun_type.return_type()=string1.type();
1803+
fun_call.function().type()=fun_type;
1804+
code.add(fun_call);
1805+
1806+
// > return class1;
1807+
code.add(code_returnt(class1));
1808+
return code;
1809+
}
1810+
1811+
/*******************************************************************\
1812+
17261813
Function: java_string_library_preprocesst::make_function_from_call
17271814
17281815
Inputs:
@@ -2545,4 +2632,12 @@ void java_string_library_preprocesst::initialize_conversion_table()
25452632
cprover_equivalent_to_java_string_returning_function
25462633
["java::java.lang.Integer.toString:(I)Ljava/lang/String;"]=
25472634
ID_cprover_string_of_int_func;
2635+
conversion_table
2636+
["java::java.lang.Object.getClass:()Ljava/lang/Class;"]=
2637+
std::bind(
2638+
&java_string_library_preprocesst::make_object_get_class_code,
2639+
this,
2640+
std::placeholders::_1,
2641+
std::placeholders::_2,
2642+
std::placeholders::_3);
25482643
}

src/java_bytecode/java_string_library_preprocess.h

+5
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,11 @@ class java_string_library_preprocesst:public messaget
151151
const source_locationt &loc,
152152
symbol_tablet &symbol_table);
153153

154+
codet make_object_get_class_code(
155+
const code_typet &type,
156+
const source_locationt &loc,
157+
symbol_tablet &symbol_table);
158+
154159
// Auxiliary functions
155160
codet code_for_scientific_notation(
156161
const exprt &arg,

src/solvers/refinement/string_constraint_generator_constants.cpp

+4-46
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,6 @@ Author: Romain Brenguier, [email protected]
1313

1414
/*******************************************************************\
1515
16-
Function: string_constraint_generatort::extract_java_string
17-
18-
Inputs: a symbol expression representing a java literal
19-
20-
Outputs: a string constant
21-
22-
Purpose: extract java string from symbol expression when they are encoded
23-
inside the symbol name
24-
25-
\*******************************************************************/
26-
27-
irep_idt string_constraint_generatort::extract_java_string(
28-
const symbol_exprt &s)
29-
{
30-
std::string tmp=id2string(s.get_identifier());
31-
std::string prefix("java::java.lang.String.Literal.");
32-
assert(has_prefix(tmp, prefix));
33-
std::string value=tmp.substr(prefix.length());
34-
return irep_idt(value);
35-
}
36-
37-
/*******************************************************************\
38-
3916
Function: string_constraint_generatort::add_axioms_for_constant
4017
4118
Inputs: a string constant
@@ -107,7 +84,9 @@ string_exprt string_constraint_generatort::add_axioms_for_empty_string(
10784
10885
Function: string_constraint_generatort::add_axioms_from_literal
10986
110-
Inputs: function application with an argument which is a string literal
87+
Inputs:
88+
f - function application with an argument which is a string literal
89+
that is a constant with a string value.
11190
11291
Outputs: string expression
11392
@@ -123,28 +102,7 @@ string_exprt string_constraint_generatort::add_axioms_from_literal(
123102
assert(args.size()==1); // Bad args to string literal?
124103

125104
const exprt &arg=args[0];
126-
irep_idt sval;
127-
128-
assert(arg.operands().size()==1);
129-
if(arg.op0().operands().size()==2 &&
130-
arg.op0().op0().id()==ID_string_constant)
131-
{
132-
// C string constant
133-
const exprt &s=arg.op0().op0();
134-
sval=to_string_constant(s).get_value();
135-
}
136-
else
137-
{
138-
// Java string constant
139-
assert(false); // TODO: Check if used. On the contrary, discard else.
140-
assert(arg.id()==ID_symbol);
141-
const exprt &s=arg.op0();
142-
143-
// It seems the value of the string is lost,
144-
// we need to recover it from the identifier
145-
sval=extract_java_string(to_symbol_expr(s));
146-
}
147-
105+
irep_idt sval=to_constant_expr(arg).get_value();
148106
const refined_string_typet &ref_type=to_refined_string_type(f.type());
149107
return add_axioms_for_constant(sval, ref_type);
150108
}

0 commit comments

Comments
 (0)