Skip to content

Commit af23573

Browse files
Matthias Güdemannmgudemann
authored andcommitted
Clean up Java pointer cast handling
1 parent e629e13 commit af23573

File tree

3 files changed

+176
-1
lines changed

3 files changed

+176
-1
lines changed

src/java_bytecode/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ SRC = java_bytecode_language.cpp java_bytecode_parse_tree.cpp \
55
java_bytecode_typecheck_type.cpp java_bytecode_internal_additions.cpp \
66
java_root_class.cpp java_bytecode_parser.cpp bytecode_info.cpp \
77
java_class_loader.cpp jar_file.cpp java_object_factory.cpp \
8-
java_bytecode_convert_method.cpp java_local_variable_table.cpp
8+
java_bytecode_convert_method.cpp java_local_variable_table.cpp \
9+
java_pointer_casts.cpp
910

1011
INCLUDES= -I ..
1112

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
2+
#include <util/std_expr.h>
3+
#include <util/std_types.h>
4+
#include <util/namespace.h>
5+
6+
#include "java_pointer_casts.h"
7+
8+
/*******************************************************************\
9+
10+
Function: clean_deref
11+
12+
Inputs: pointer
13+
14+
Outputs: dereferenced pointer
15+
16+
Purpose: dereference pointer expression
17+
18+
\*******************************************************************/
19+
20+
exprt clean_deref(const exprt ptr)
21+
{
22+
return ptr.id()==ID_address_of
23+
? ptr.op0()
24+
: dereference_exprt(ptr, ptr.type().subtype());
25+
}
26+
27+
/*******************************************************************\
28+
29+
Function: find_superclass_with_type
30+
31+
Inputs: pointer
32+
target type to search
33+
34+
Outputs: true iff a super class with target type is found
35+
36+
Purpose:
37+
38+
\*******************************************************************/
39+
40+
41+
bool find_superclass_with_type(exprt &ptr,const typet &target_type,
42+
const namespacet &ns)
43+
{
44+
45+
while(true)
46+
{
47+
48+
const typet ptr_base=ns.follow(ptr.type().subtype());
49+
50+
if(ptr_base.id()!=ID_struct)
51+
return false;
52+
53+
const struct_typet &base_struct=to_struct_type(ptr_base);
54+
55+
if(base_struct.components().size()==0)
56+
return false;
57+
58+
const typet &first_field_type=
59+
ns.follow(base_struct.components()[0].type());
60+
ptr=clean_deref(ptr);
61+
ptr=member_exprt(ptr,base_struct.components()[0].get_name(),
62+
first_field_type);
63+
ptr=address_of_exprt(ptr);
64+
65+
if(first_field_type==target_type)
66+
return true;
67+
}
68+
}
69+
70+
71+
/*******************************************************************\
72+
73+
Function: look_through_casts
74+
75+
Inputs: input expression
76+
77+
Outputs: recursively search target of typecast
78+
79+
Purpose:
80+
81+
\*******************************************************************/
82+
83+
static const exprt& look_through_casts(const exprt& in)
84+
{
85+
if(in.id()==ID_typecast)
86+
{
87+
assert(in.type().id()==ID_pointer);
88+
return look_through_casts(in.op0());
89+
}
90+
else {
91+
return in;
92+
}
93+
}
94+
95+
96+
/*******************************************************************\
97+
98+
Function: make_clean_pointer_cast
99+
100+
Inputs: raw pointer
101+
target type
102+
namespace
103+
104+
Outputs: cleaned up typecast expression
105+
106+
Purpose:
107+
108+
\*******************************************************************/
109+
110+
exprt make_clean_pointer_cast(const exprt &rawptr,const typet &target_type,
111+
const namespacet &ns)
112+
{
113+
114+
assert(target_type.id()==ID_pointer &&
115+
"Non-pointer target in make_clean_pointer_cast?");
116+
117+
const exprt &ptr=look_through_casts(rawptr);
118+
119+
if(ptr.type()==target_type)
120+
return ptr;
121+
122+
if(ptr.type().subtype()==empty_typet() ||
123+
target_type.subtype()==empty_typet())
124+
return typecast_exprt(ptr,target_type);
125+
126+
const typet &target_base=ns.follow(target_type.subtype());
127+
128+
exprt bare_ptr=ptr;
129+
while(bare_ptr.id()==ID_typecast)
130+
{
131+
assert(bare_ptr.type().id()==ID_pointer &&
132+
"Non-pointer in make_clean_pointer_cast?");
133+
if(bare_ptr.type().subtype()==empty_typet())
134+
bare_ptr=bare_ptr.op0();
135+
}
136+
137+
assert(bare_ptr.type().id()==ID_pointer &&
138+
"Non-pointer in make_clean_pointer_cast?");
139+
140+
if(bare_ptr.type()==target_type)
141+
return bare_ptr;
142+
143+
exprt superclass_ptr=bare_ptr;
144+
if(find_superclass_with_type(superclass_ptr,target_base,ns))
145+
return superclass_ptr;
146+
147+
return typecast_exprt(bare_ptr,target_type);
148+
}
149+
150+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*******************************************************************\
2+
3+
Module: JAVA Pointer Casts
4+
5+
Author: DiffBlue
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H
10+
#define CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H
11+
12+
exprt clean_deref(const exprt ptr);
13+
14+
bool find_superclass_with_type(
15+
exprt &ptr,
16+
const typet &target_type,
17+
const namespacet &ns);
18+
19+
exprt make_clean_pointer_cast(
20+
const exprt &ptr,
21+
const typet &target_type,
22+
const namespacet &ns);
23+
24+
#endif // CPROVER_JAVA_BYTECODE_JAVA_POINTER_CASTS_H

0 commit comments

Comments
 (0)