Skip to content

Commit 5787def

Browse files
committed
Treat all anonymous locals as void*
The existing code tried to infer local type from the assignment, but (a) the information wasn't recorded in the variable table leading to later misuse, and (b) I'm not convinced it's safe to infer types for locals this way because a pattern like if(x) a = new A(); else a = new B(); (where A and B are unrelated) can use the same local slot for both classes. In this case we'd want to give it java.lang.Object* type. In view of all this it is surely simplest to just treat locals as generic, like the bytecode does, then cast the void* to needed types at use sites.
1 parent c2c25b4 commit 5787def

File tree

1 file changed

+13
-10
lines changed

1 file changed

+13
-10
lines changed

src/java_bytecode/java_bytecode_convert.cpp

+13-10
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,7 @@ codet java_bytecode_convertt::convert_instructions(
808808
}
809809
else if(statement=="invokedynamic")
810810
{
811-
// not used in Java
811+
// TODO: Java 8 lambdas use this.
812812
code_typet &code_type=to_code_type(arg0.type());
813813
const code_typet::parameterst &parameters(code_type.parameters());
814814

@@ -866,17 +866,21 @@ codet java_bytecode_convertt::convert_instructions(
866866

867867
// do some type adjustment for the arguments,
868868
// as Java promotes arguments
869+
// Also cast pointers since intermediate locals
870+
// can be void*.
869871

870872
for(unsigned i=0; i<parameters.size(); i++)
871873
{
872874
const typet &type=parameters[i].type();
873875
if(type==java_boolean_type() ||
874876
type==java_char_type() ||
875877
type==java_byte_type() ||
876-
type==java_short_type())
878+
type==java_short_type() ||
879+
type.id()==ID_pointer)
877880
{
878881
assert(i<call.arguments().size());
879-
call.arguments()[i].make_typecast(type);
882+
if(type!=call.arguments()[i].type())
883+
call.arguments()[i].make_typecast(type);
880884
}
881885
}
882886

@@ -968,13 +972,12 @@ codet java_bytecode_convertt::convert_instructions(
968972
assert(op.size()==1 && results.empty());
969973

970974
exprt var=variable(arg0, statement[0]);
971-
972-
const bool is_array('a' == statement[0]);
973-
974-
if(is_array)
975-
var.type()=op[0].type();
976975

977-
c=code_assignt(var, op[0]);
976+
exprt toassign=op[0];
977+
if('a'==statement[0] && toassign.type()!=var.type())
978+
toassign=typecast_exprt(toassign,var.type());
979+
980+
c=code_assignt(var,toassign);
978981
}
979982
else if(statement==patternt("?aload"))
980983
{
@@ -1135,7 +1138,7 @@ codet java_bytecode_convertt::convert_instructions(
11351138
irep_idt number=to_constant_expr(arg0).get_value();
11361139
assert(op.size()==1 && results.empty());
11371140
code_ifthenelset code_branch;
1138-
const typecast_exprt lhs(op[0], pointer_typet());
1141+
const typecast_exprt lhs(op[0], pointer_typet(empty_typet()));
11391142
const exprt rhs(gen_zero(lhs.type()));
11401143
code_branch.cond()=binary_relation_exprt(lhs, ID_notequal, rhs);
11411144
code_branch.then_case()=code_gotot(label(number));

0 commit comments

Comments
 (0)