Skip to content

Commit 8187bdd

Browse files
author
Matthias Güdemann
authored
Merge pull request diffblue#2526 from jeannielynnmoulton/jeannie/AnonymousInnerClasses
Captures anonymous inner class information
2 parents d20a12e + af0ce5a commit 8187bdd

File tree

6 files changed

+45
-7
lines changed

6 files changed

+45
-7
lines changed

jbmc/src/java_bytecode/java_bytecode_convert_class.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ void java_bytecode_convert_classt::convert(
278278
class_type.set_final(c.is_final);
279279
class_type.set_is_inner_class(c.is_inner_class);
280280
class_type.set_is_static_class(c.is_static_class);
281+
class_type.set_is_anonymous_class(c.is_anonymous_class);
281282
if(c.is_enum)
282283
{
283284
if(max_array_length != 0 && c.enum_elements > max_array_length)

jbmc/src/java_bytecode/java_bytecode_parse_tree.h

+1
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ class java_bytecode_parse_treet
219219
bool is_annotation = false;
220220
bool is_inner_class = false;
221221
bool is_static_class = false;
222+
bool is_anonymous_class = false;
222223
bool attribute_bootstrapmethods_read = false;
223224
size_t enum_elements=0;
224225

jbmc/src/java_bytecode/java_bytecode_parser.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -1613,7 +1613,7 @@ void java_bytecode_parsert::rinner_classes_attribute(
16131613
{
16141614
u2 inner_class_info_index = read_u2();
16151615
u2 outer_class_info_index = read_u2();
1616-
UNUSED u2 inner_name_index = read_u2();
1616+
u2 inner_name_index = read_u2();
16171617
u2 inner_class_access_flags = read_u2();
16181618

16191619
std::string inner_class_info_name =
@@ -1634,6 +1634,9 @@ void java_bytecode_parsert::rinner_classes_attribute(
16341634
if(!is_inner_class)
16351635
continue;
16361636
parsed_class.is_static_class = is_static;
1637+
// This is a marker that a class is anonymous.
1638+
if(inner_name_index == 0)
1639+
parsed_class.is_anonymous_class = true;
16371640
// Note that if outer_class_info_index == 0, the inner class is an anonymous
16381641
// or local class, and is treated as private.
16391642
if(outer_class_info_index == 0)

jbmc/src/java_bytecode/java_types.h

+9
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,15 @@ class java_class_typet:public class_typet
131131
return set(ID_is_static, is_static_class);
132132
}
133133

134+
const bool get_is_anonymous_class() const
135+
{
136+
return get_bool(ID_is_anonymous);
137+
}
138+
139+
void set_is_anonymous_class(const bool &is_anonymous_class)
140+
{
141+
return set(ID_is_anonymous, is_anonymous_class);
142+
}
134143

135144
bool get_final()
136145
{

jbmc/unit/java_bytecode/java_bytecode_parser/parse_java_attributes.cpp

+29-6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ SCENARIO(
2828
new_symbol_table.lookup_ref("java::InnerClasses$PublicInnerClass");
2929
const java_class_typet java_class =
3030
to_java_class_type(class_symbol.type);
31+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
3132
REQUIRE(java_class.get_is_inner_class());
3233
REQUIRE(java_class.get_access() == ID_public);
3334
}
@@ -40,6 +41,7 @@ SCENARIO(
4041
new_symbol_table.lookup_ref("java::InnerClasses$DefaultInnerClass");
4142
const java_class_typet java_class =
4243
to_java_class_type(class_symbol.type);
44+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
4345
REQUIRE(java_class.get_is_inner_class());
4446
REQUIRE(java_class.get_access() == ID_default);
4547
}
@@ -52,6 +54,7 @@ SCENARIO(
5254
new_symbol_table.lookup_ref("java::InnerClasses$ProtectedInnerClass");
5355
const java_class_typet java_class =
5456
to_java_class_type(class_symbol.type);
57+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
5558
REQUIRE(java_class.get_is_inner_class());
5659
REQUIRE(java_class.get_access() == ID_protected);
5760
}
@@ -64,6 +67,7 @@ SCENARIO(
6467
new_symbol_table.lookup_ref("java::InnerClasses$PrivateInnerClass");
6568
const java_class_typet java_class =
6669
to_java_class_type(class_symbol.type);
70+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
6771
REQUIRE(java_class.get_is_inner_class());
6872
REQUIRE(java_class.get_access() == ID_private);
6973
}
@@ -81,6 +85,7 @@ SCENARIO(
8185
"java::InnerClassesDefault$PublicInnerClass");
8286
const java_class_typet java_class =
8387
to_java_class_type(class_symbol.type);
88+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
8489
REQUIRE(java_class.get_is_inner_class());
8590
REQUIRE(java_class.get_access() == ID_public);
8691
}
@@ -93,6 +98,7 @@ SCENARIO(
9398
"java::InnerClassesDefault$DefaultInnerClass");
9499
const java_class_typet java_class =
95100
to_java_class_type(class_symbol.type);
101+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
96102
REQUIRE(java_class.get_is_inner_class());
97103
REQUIRE(java_class.get_access() == ID_default);
98104
}
@@ -105,6 +111,7 @@ SCENARIO(
105111
"java::InnerClassesDefault$ProtectedInnerClass");
106112
const java_class_typet java_class =
107113
to_java_class_type(class_symbol.type);
114+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
108115
REQUIRE(java_class.get_is_inner_class());
109116
REQUIRE(java_class.get_access() == ID_protected);
110117
}
@@ -117,6 +124,7 @@ SCENARIO(
117124
"java::InnerClassesDefault$PrivateInnerClass");
118125
const java_class_typet java_class =
119126
to_java_class_type(class_symbol.type);
127+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
120128
REQUIRE(java_class.get_is_inner_class());
121129
REQUIRE(java_class.get_access() == ID_private);
122130
}
@@ -140,6 +148,7 @@ SCENARIO(
140148
"PublicDoublyNestedInnerClass");
141149
const java_class_typet java_class =
142150
to_java_class_type(class_symbol.type);
151+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
143152
REQUIRE(java_class.get_is_inner_class());
144153
REQUIRE(java_class.get_access() == ID_public);
145154
}
@@ -155,6 +164,7 @@ SCENARIO(
155164
"DefaultDoublyNestedInnerClass");
156165
const java_class_typet java_class =
157166
to_java_class_type(class_symbol.type);
167+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
158168
REQUIRE(java_class.get_is_inner_class());
159169
REQUIRE(java_class.get_access() == ID_default);
160170
}
@@ -170,6 +180,7 @@ SCENARIO(
170180
"ProtectedDoublyNestedInnerClass");
171181
const java_class_typet java_class =
172182
to_java_class_type(class_symbol.type);
183+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
173184
REQUIRE(java_class.get_is_inner_class());
174185
REQUIRE(java_class.get_access() == ID_protected);
175186
}
@@ -185,6 +196,7 @@ SCENARIO(
185196
"PrivateDoublyNestedInnerClass");
186197
const java_class_typet java_class =
187198
to_java_class_type(class_symbol.type);
199+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
188200
REQUIRE(java_class.get_is_inner_class());
189201
REQUIRE(java_class.get_access() == ID_private);
190202
}
@@ -198,51 +210,55 @@ SCENARIO(
198210
"ContainsAnonymousClass", "./java_bytecode/java_bytecode_parser");
199211
WHEN("Parsing the InnerClasses attribute for a public anonymous class")
200212
{
201-
THEN("The class should be marked as public")
213+
THEN("The class should be marked as private and anonymous")
202214
{
203215
const symbolt &class_symbol =
204216
new_symbol_table.lookup_ref("java::ContainsAnonymousClass$1");
205217
const java_class_typet java_class =
206218
to_java_class_type(class_symbol.type);
207219
REQUIRE(java_class.get_is_inner_class());
220+
REQUIRE(java_class.get_is_anonymous_class());
208221
REQUIRE(java_class.get_access() == ID_private);
209222
}
210223
}
211224
WHEN(
212225
"Parsing the InnerClasses attribute for a package-private anonymous "
213226
"class")
214227
{
215-
THEN("The class should be marked as default")
228+
THEN("The class should be marked as private and anonymous")
216229
{
217230
const symbolt &class_symbol =
218231
new_symbol_table.lookup_ref("java::ContainsAnonymousClass$2");
219232
const java_class_typet java_class =
220233
to_java_class_type(class_symbol.type);
221234
REQUIRE(java_class.get_is_inner_class());
235+
REQUIRE(java_class.get_is_anonymous_class());
222236
REQUIRE(java_class.get_access() == ID_private);
223237
}
224238
}
225239
WHEN("Parsing the InnerClasses attribute for a protected anonymous class")
226240
{
227-
THEN("The class should be marked as protected")
241+
THEN("The class should be marked as private and anonymous")
228242
{
229243
const symbolt &class_symbol =
230244
new_symbol_table.lookup_ref("java::ContainsAnonymousClass$3");
231245
const java_class_typet java_class =
232246
to_java_class_type(class_symbol.type);
233247
REQUIRE(java_class.get_is_inner_class());
248+
REQUIRE(java_class.get_is_anonymous_class());
234249
REQUIRE(java_class.get_access() == ID_private);
235250
}
236251
}
237252
WHEN("Parsing the InnerClasses attribute for a private anonymous class")
238253
{
239-
THEN("The class should be marked as private")
254+
THEN("The class should be marked as private and anonymous")
240255
{
241256
const symbolt &class_symbol =
242257
new_symbol_table.lookup_ref("java::ContainsAnonymousClass$4");
243258
const java_class_typet java_class =
244259
to_java_class_type(class_symbol.type);
245260
REQUIRE(java_class.get_is_inner_class());
261+
REQUIRE(java_class.get_is_anonymous_class());
246262
REQUIRE(java_class.get_access() == ID_private);
247263
}
248264
}
@@ -263,6 +279,7 @@ SCENARIO(
263279
to_java_class_type(class_symbol.type);
264280
REQUIRE(java_class.get_is_inner_class());
265281
REQUIRE(java_class.get_access() == ID_private);
282+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
266283
}
267284
}
268285
}
@@ -281,6 +298,7 @@ SCENARIO(
281298
to_java_class_type(class_symbol.type);
282299
REQUIRE(java_class.get_is_inner_class());
283300
REQUIRE(java_class.get_is_static_class());
301+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
284302
}
285303
}
286304
WHEN("Parsing the InnerClasses attribute for a non-static inner class ")
@@ -293,32 +311,35 @@ SCENARIO(
293311
to_java_class_type(class_symbol.type);
294312
REQUIRE(java_class.get_is_inner_class());
295313
REQUIRE_FALSE(java_class.get_is_static_class());
314+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
296315
}
297316
}
298317
}
299318
GIVEN("Some class with a static anonymous class")
300319
{
301320
WHEN("Parsing the InnerClasses attribute for a static anonymous class ")
302321
{
303-
THEN("The class should be marked as static")
322+
THEN("The class should be marked as static and anonymous")
304323
{
305324
const symbolt &class_symbol =
306325
new_symbol_table.lookup_ref("java::StaticInnerClass$1");
307326
const java_class_typet java_class =
308327
to_java_class_type(class_symbol.type);
309328
REQUIRE(java_class.get_is_inner_class());
329+
REQUIRE(java_class.get_is_anonymous_class());
310330
REQUIRE(java_class.get_is_static_class());
311331
}
312332
}
313333
WHEN("Parsing the InnerClasses attribute for a non-static anonymous class ")
314334
{
315-
THEN("The class should not be marked as static")
335+
THEN("The class should be marked as anonymous and not static")
316336
{
317337
const symbolt &class_symbol =
318338
new_symbol_table.lookup_ref("java::StaticInnerClass$2");
319339
const java_class_typet java_class =
320340
to_java_class_type(class_symbol.type);
321341
REQUIRE(java_class.get_is_inner_class());
342+
REQUIRE(java_class.get_is_anonymous_class());
322343
REQUIRE_FALSE(java_class.get_is_static_class());
323344
}
324345
}
@@ -337,6 +358,7 @@ SCENARIO(
337358
to_java_class_type(class_symbol.type);
338359
REQUIRE(java_class.get_is_inner_class());
339360
REQUIRE_FALSE(java_class.get_is_static_class());
361+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
340362
}
341363
}
342364
WHEN(
@@ -351,6 +373,7 @@ SCENARIO(
351373
to_java_class_type(class_symbol.type);
352374
REQUIRE(java_class.get_is_inner_class());
353375
REQUIRE_FALSE(java_class.get_is_static_class());
376+
REQUIRE_FALSE(java_class.get_is_anonymous_class());
354377
}
355378
}
356379
}

src/util/irep_ids.def

+1
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,7 @@ IREP_ID_TWO(C_must_not_throw, #must_not_throw)
676676
IREP_ID_ONE(always_inline)
677677
IREP_ID_ONE(is_always_inline)
678678
IREP_ID_ONE(is_inner_class)
679+
IREP_ID_ONE(is_anonymous)
679680

680681
// Projects depending on this code base that wish to extend the list of
681682
// available ids should provide a file local_irep_ids.h in their source tree and

0 commit comments

Comments
 (0)