Skip to content

Commit 2f7925d

Browse files
author
svorenova
committed
Adding unit test for recursive generic class
1 parent e8c75ac commit 2f7925d

11 files changed

+91
-16
lines changed

src/java_bytecode/java_bytecode_convert_class.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ void java_bytecode_convert_classt::convert(const classt &c)
119119
{
120120
// Do nothing: we don't support parsing for example double bounded or
121121
// two entry elements
122+
122123
}
123124
}
124125

@@ -218,8 +219,9 @@ void java_bytecode_convert_classt::convert(
218219
typet field_type;
219220
if(f.signature.has_value())
220221
{
221-
field_type=java_type_from_string(
222-
f.signature.value(),
222+
field_type=java_type_from_string_with_exception(
223+
f.descriptor,
224+
f.signature,
223225
id2string(class_symbol.name));
224226

225227
/// this is for a free type variable, e.g., a field of the form `T f;`

src/java_bytecode/java_bytecode_convert_method.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,9 @@ void java_bytecode_convert_methodt::convert(
366366
typet t;
367367
if(v.signature.has_value())
368368
{
369-
t=java_type_from_string(
370-
v.signature.value(),
369+
t=java_type_from_string_with_exception(
370+
v.descriptor,
371+
v.signature,
371372
id2string(class_symbol.name));
372373
}
373374
else

src/java_bytecode/java_bytecode_parser.cpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,9 @@ void java_bytecode_parsert::get_class_refs()
339339
typet field_type;
340340
if(field.signature.has_value())
341341
{
342-
field_type=java_type_from_string(
343-
field.signature.value(),
342+
field_type=java_type_from_string_with_exception(
343+
field.descriptor,
344+
field.signature,
344345
"java::"+id2string(parse_tree.parsed_class.name));
345346
}
346347
else
@@ -354,8 +355,9 @@ void java_bytecode_parsert::get_class_refs()
354355
typet method_type;
355356
if(method.signature.has_value())
356357
{
357-
method_type=java_type_from_string(
358-
method.signature.value(),
358+
method_type=java_type_from_string_with_exception(
359+
method.descriptor,
360+
method.signature,
359361
"java::"+id2string(parse_tree.parsed_class.name));
360362
}
361363
else
@@ -367,8 +369,9 @@ void java_bytecode_parsert::get_class_refs()
367369
typet var_type;
368370
if(var.signature.has_value())
369371
{
370-
var_type=java_type_from_string(
371-
var.signature.value(),
372+
var_type=java_type_from_string_with_exception(
373+
var.descriptor,
374+
var.signature,
372375
"java::"+id2string(parse_tree.parsed_class.name));
373376
}
374377
else

src/java_bytecode/java_local_variable_table.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,16 @@ void java_bytecode_convert_methodt::setup_local_variables(
770770
#endif
771771
typet t;
772772
if(v.var.signature.has_value())
773-
t=java_type_from_string(v.var.signature.value());
773+
{
774+
try
775+
{
776+
t=java_type_from_string(v.var.signature.value());
777+
}
778+
catch(unsupported_java_class_siganture_exceptiont &e)
779+
{
780+
t=java_type_from_string(v.var.descriptor);
781+
}
782+
}
774783
else
775784
t=java_type_from_string(v.var.descriptor);
776785

src/java_bytecode/java_types.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,8 @@ typet java_type_from_string(
325325
{
326326
std::size_t e_pos=find_closing_delimiter(src, f_pos, '<', '>');
327327
if(e_pos==std::string::npos)
328-
return nil_typet();
328+
throw unsupported_java_class_siganture_exceptiont(
329+
"recursive generic");
329330

330331
// construct container type
331332
std::string generic_container_class=src.substr(1, f_pos-1);
@@ -520,7 +521,7 @@ std::vector<typet> java_generic_type_from_string(
520521
std::string signature(src.substr(1, signature_end-1));
521522

522523
if(signature.find(";:")!=std::string::npos)
523-
throw unsupported_java_class_siganture_exceptiont();
524+
throw unsupported_java_class_siganture_exceptiont("multiple bounds");
524525

525526
PRECONDITION(signature[signature.size()-1]==';');
526527

src/java_bytecode/java_types.h

+18-3
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,25 @@ inline const typet &java_generics_class_type_bound(
356356
class unsupported_java_class_siganture_exceptiont:public std::logic_error
357357
{
358358
public:
359-
unsupported_java_class_siganture_exceptiont():
359+
explicit unsupported_java_class_siganture_exceptiont(std::string type):
360360
std::logic_error(
361-
"Unsupported class signature: multiple bounds")
362-
{}
361+
"Unsupported class signature: "+type)
362+
{
363+
}
363364
};
364365

366+
inline typet java_type_from_string_with_exception(
367+
const std::string &descriptor,
368+
const optionalt<std::string> &signature,
369+
const std::string &class_name) {
370+
try
371+
{
372+
return java_type_from_string(signature.value(), class_name);
373+
}
374+
catch (unsupported_java_class_siganture_exceptiont &e)
375+
{
376+
return java_type_from_string(descriptor, class_name);
377+
}
378+
}
379+
365380
#endif // CPROVER_JAVA_BYTECODE_JAVA_TYPES_H
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class RecursiveGeneric extends SimpleRecursiveGeneric<RecursiveGeneric>
2+
{
3+
4+
}
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class SimpleRecursiveGeneric<T extends SimpleRecursiveGeneric<T>>
2+
{
3+
public T t;
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*******************************************************************\
2+
3+
Module: Unit tests for parsing generic classes
4+
5+
Author: DiffBlue Limited. All rights reserved.
6+
7+
\*******************************************************************/
8+
9+
#include <catch.hpp>
10+
11+
#include <util/config.h>
12+
#include <util/cmdline.h>
13+
#include <util/language.h>
14+
#include <util/prefix.h>
15+
16+
#include <java_bytecode/java_bytecode_language.h>
17+
#include <src/java_bytecode/load_java_class.h>
18+
19+
#include <iostream>
20+
#include <util/namespace.h>
21+
22+
SCENARIO(
23+
"java_bytecode_parse_recursive_generic_class",
24+
"[core][java_bytecode][java_bytecode_parse_generics]")
25+
{
26+
const symbol_tablet &new_symbol_table=
27+
load_java_class("RecursiveGeneric", ""
28+
"./java_bytecode/java_bytecode_parse_generics");
29+
30+
std::string class_prefix="java::RecursiveGeneric";
31+
32+
REQUIRE(new_symbol_table.has_symbol(class_prefix));
33+
34+
// TODO: Extend this unit test when recursive generic types are correctly
35+
// parsed.
36+
}

0 commit comments

Comments
 (0)