Skip to content

Commit

Permalink
Merge pull request #1533 from mgudemann/fix/support_class_bounds_gene…
Browse files Browse the repository at this point in the history
…rics

TG-1179 Skip '::' instead of just ':' for class bounds in generics
  • Loading branch information
Matthias Güdemann authored Nov 2, 2017
2 parents b25630a + 6b88eb8 commit 4b36fc6
Show file tree
Hide file tree
Showing 13 changed files with 49 additions and 2 deletions.
Binary file added regression/cbmc-java/generic_class_bound1/A.class
Binary file not shown.
Binary file added regression/cbmc-java/generic_class_bound1/B.class
Binary file not shown.
Binary file added regression/cbmc-java/generic_class_bound1/C.class
Binary file not shown.
Binary file added regression/cbmc-java/generic_class_bound1/Gn.class
Binary file not shown.
15 changes: 15 additions & 0 deletions regression/cbmc-java/generic_class_bound1/Gn.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
interface A{}
interface B{}
interface C{}
interface L<T> extends A,B,C{}

public class Gn<T extends L<? extends B>>{
Gn<?> ex1;
public void foo1(Gn<?> ex1){
if(ex1 != null)
this.ex1 = ex1;
}
public static void main(String[] args) {
System.out.println("ddfsdf");
}
}
Binary file added regression/cbmc-java/generic_class_bound1/L.class
Binary file not shown.
11 changes: 11 additions & 0 deletions regression/cbmc-java/generic_class_bound1/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CORE
Gn.class
--cover location
^EXIT=0$
^SIGNAL=0$
.*file Gn.java line 6 function java::Gn.\<init\>:\(\)V bytecode-index 1 block 1: FAILED
.*file Gn.java line 9 function java::Gn.foo1:\(LGn;\)V bytecode-index 1 block 1: FAILED
.*file Gn.java line 10 function java::Gn.foo1:\(LGn;\)V bytecode-index 4 block 2: FAILED
.*file Gn.java line 11 function java::Gn.foo1:\(LGn;\)V bytecode-index 5 block 3: FAILED
.*file Gn.java line 13 function java::Gn.main:\(\[Ljava/lang/String;\)V bytecode-index 2 block 1: SATISFIED
--
17 changes: 15 additions & 2 deletions src/java_bytecode/java_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,8 @@ char java_char_from_type(const typet &type)
/// Converts the content of a generic class type into a vector of Java types,
/// that is each type variable of the class has one entry in the returned
/// vector.
/// This also supports parsing of bounds in the form of `<T:CBound>` for classes
/// or `<T::IBound>` for interfaces.
///
/// For example for `HashMap<K, V>` a vector with two elements would be returned
///
Expand All @@ -607,8 +609,9 @@ std::vector<typet> java_generic_type_from_string(
const std::string &class_name,
const std::string &src)
{
/// the class signature is of the form <TX:Bound_X;:BoundZ;TY:Bound_Y;>
size_t signature_end=find_closing_delimiter(src, 0, '<', '>');
/// the class signature is of the form <TX:Bound_X;:BoundZ;TY:Bound_Y;> or of
/// the form <TX::Bound_X;:BoundZ;TY:Bound_Y;> if Bound_X is an interface
size_t signature_end = find_closing_delimiter(src, 0, '<', '>');
INVARIANT(
src[0]=='<' && signature_end!=std::string::npos,
"Class signature has unexpected format");
Expand All @@ -625,6 +628,16 @@ std::vector<typet> java_generic_type_from_string(
{
size_t bound_sep=signature.find(':');
INVARIANT(bound_sep!=std::string::npos, "No bound for type variable.");

// is bound an interface?
// in this case the separator is '::'
if(signature[bound_sep + 1] == ':')
{
INVARIANT(
signature[bound_sep + 2] != ':', "Unknown bound for type variable.");
bound_sep++;
}

std::string type_var_name(
"java::"+class_name+"::"+signature.substr(0, bound_sep));
std::string bound_type(signature.substr(bound_sep+1, var_sep-bound_sep));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class C{
}
interface I{
}
class interface_bound<T extends I> {
}
class class_bound<T extends C> {
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit 4b36fc6

Please sign in to comment.