From 9103a3125b21be48596268fa4579b5dc9b82ab0e Mon Sep 17 00:00:00 2001 From: thk123 Date: Thu, 5 Jul 2018 15:04:38 +0100 Subject: [PATCH 1/2] Read the bride flag for methods This is used for compiler generated methods to deal with type erasure. --- .../java_bytecode/java_bytecode_convert_method.cpp | 3 +++ jbmc/src/java_bytecode/java_bytecode_parse_tree.h | 11 ++++++----- jbmc/src/java_bytecode/java_bytecode_parser.cpp | 1 + src/util/irep_ids.def | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/jbmc/src/java_bytecode/java_bytecode_convert_method.cpp b/jbmc/src/java_bytecode/java_bytecode_convert_method.cpp index 8e0a1ba9120..a95ed0f9159 100644 --- a/jbmc/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/jbmc/src/java_bytecode/java_bytecode_convert_method.cpp @@ -371,6 +371,9 @@ void java_bytecode_convert_method_lazy( if(m.is_static) member_type.set(ID_is_static, true); + if(m.is_bridge) + member_type.set(ID_is_bridge_method, m.is_bridge); + // do we need to add 'this' as a parameter? if(!m.is_static) { diff --git a/jbmc/src/java_bytecode/java_bytecode_parse_tree.h b/jbmc/src/java_bytecode/java_bytecode_parse_tree.h index 431dd4804f5..ac7e6a21bd2 100644 --- a/jbmc/src/java_bytecode/java_bytecode_parse_tree.h +++ b/jbmc/src/java_bytecode/java_bytecode_parse_tree.h @@ -95,7 +95,7 @@ class java_bytecode_parse_treet { public: irep_idt base_name; - bool is_native, is_abstract, is_synchronized; + bool is_native, is_abstract, is_synchronized, is_bridge; source_locationt source_location; typedef std::vector instructionst; @@ -177,10 +177,11 @@ class java_bytecode_parse_treet virtual void output(std::ostream &out) const; - methodt(): - is_native(false), - is_abstract(false), - is_synchronized(false) + methodt() + : is_native(false), + is_abstract(false), + is_synchronized(false), + is_bridge(false) { } diff --git a/jbmc/src/java_bytecode/java_bytecode_parser.cpp b/jbmc/src/java_bytecode/java_bytecode_parser.cpp index 82c66bf5c5e..c13dd1eb0b5 100644 --- a/jbmc/src/java_bytecode/java_bytecode_parser.cpp +++ b/jbmc/src/java_bytecode/java_bytecode_parser.cpp @@ -1765,6 +1765,7 @@ void java_bytecode_parsert::rmethod(classt &parsed_class) method.is_private=(access_flags&ACC_PRIVATE)!=0; method.is_synchronized=(access_flags&ACC_SYNCHRONIZED)!=0; method.is_native=(access_flags&ACC_NATIVE)!=0; + method.is_bridge = (access_flags & ACC_BRIDGE) != 0; method.name=pool_entry(name_index).s; method.base_name=pool_entry(name_index).s; method.descriptor=id2string(pool_entry(descriptor_index).s); diff --git a/src/util/irep_ids.def b/src/util/irep_ids.def index e2d7d160112..5bbbc894d4b 100644 --- a/src/util/irep_ids.def +++ b/src/util/irep_ids.def @@ -675,6 +675,7 @@ IREP_ID_ONE(interface) IREP_ID_TWO(C_must_not_throw, #must_not_throw) IREP_ID_ONE(is_inner_class) IREP_ID_ONE(is_anonymous) +IREP_ID_ONE(is_bridge_method) // Projects depending on this code base that wish to extend the list of // available ids should provide a file local_irep_ids.h in their source tree and From ac9bc2de67dbf2d1a7d3cce7adbf958614653faf Mon Sep 17 00:00:00 2001 From: thk123 Date: Thu, 5 Jul 2018 17:35:30 +0100 Subject: [PATCH 2/2] Adding unit test for checking bridge methods attribute is parsed correctly --- .../ClassWithBridgeMethod.class | Bin 0 -> 620 bytes .../ClassWithBridgeMethod.java | 5 ++ .../convert_method.cpp | 55 ++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 jbmc/unit/java_bytecode/java_bytecode_convert_method/ClassWithBridgeMethod.class create mode 100644 jbmc/unit/java_bytecode/java_bytecode_convert_method/ClassWithBridgeMethod.java create mode 100644 jbmc/unit/java_bytecode/java_bytecode_convert_method/convert_method.cpp diff --git a/jbmc/unit/java_bytecode/java_bytecode_convert_method/ClassWithBridgeMethod.class b/jbmc/unit/java_bytecode/java_bytecode_convert_method/ClassWithBridgeMethod.class new file mode 100644 index 0000000000000000000000000000000000000000..e1e1fdc63752738a1308e6275fdc448ebc3b228e GIT binary patch literal 620 zcmZ`$O;5r=6r61fwTObqhjQ}MCdwITsF*l0amtWxOJ7DE2EA4vG8nyJEEsaO z^u@zsHWJ~0k33=ucHnSt$U~{l328*GoHJDHp2z3&CmFdnp&U=dy@=dk++whtVD`*I zF$fr{wH>nh9YZRJToE#qYW9@B@TSN8N%L_u6;9Mr_f}s{d>$=AiqhSbtTDZKqYByH zv9CkHGW}o?I^tHUw^g^szfeK4NW-L9TNPOx;E*BzKQTjbMXmDSj6S>pdMy19osg`l z?$N19$Ou!753o0CG+0#AF-d8u&n^Ynrw-K9YN~4ZnouLu^jB5aCiQr-yu3{&l_ICy j@?G-CCmxr?Di5o1{tfLN8&>Nfti(#gQM|B#;~0y7-;jQs literal 0 HcmV?d00001 diff --git a/jbmc/unit/java_bytecode/java_bytecode_convert_method/ClassWithBridgeMethod.java b/jbmc/unit/java_bytecode/java_bytecode_convert_method/ClassWithBridgeMethod.java new file mode 100644 index 00000000000..f695e0ea87c --- /dev/null +++ b/jbmc/unit/java_bytecode/java_bytecode_convert_method/ClassWithBridgeMethod.java @@ -0,0 +1,5 @@ +public class ClassWithBridgeMethod implements Comparable { + public int compareTo(ClassWithBridgeMethod other) { + return 0; + } +} diff --git a/jbmc/unit/java_bytecode/java_bytecode_convert_method/convert_method.cpp b/jbmc/unit/java_bytecode/java_bytecode_convert_method/convert_method.cpp new file mode 100644 index 00000000000..a925d8469f8 --- /dev/null +++ b/jbmc/unit/java_bytecode/java_bytecode_convert_method/convert_method.cpp @@ -0,0 +1,55 @@ +/*******************************************************************\ + + Module: Unit tests for converting constructors and static initializers + + Author: Diffblue Limited. + +\*******************************************************************/ + +#include + +#include + +#include +#include + +SCENARIO( + "java_bytecode_convert_bridge_method", + "[core][java_bytecode][java_bytecode_convert_method]") +{ + GIVEN("A class with a bridge method") + { + const symbol_tablet symbol_table = load_java_class( + "ClassWithBridgeMethod", "./java_bytecode/java_bytecode_convert_method"); + + const std::string method_name = "java::ClassWithBridgeMethod.compareTo"; + + WHEN("When parsing the bridge method") + { + const symbolt function_symbol = + symbol_table.lookup_ref(method_name + ":(Ljava/lang/Object;)I"); + + const code_typet &function_type = + require_type::require_code(function_symbol.type); + THEN("The method should be marked as a bridge method") + { + REQUIRE(function_type.get_bool(ID_is_bridge_method)); + } + } + WHEN("When parsing a non-bridge method") + { + THEN("THe method should not be marked as a bridge method") + { + const symbolt function_symbol = + symbol_table.lookup_ref(method_name + ":(LClassWithBridgeMethod;)I"); + + const code_typet &function_type = + require_type::require_code(function_symbol.type); + THEN("The method should be marked as a bridge method") + { + REQUIRE_FALSE(function_type.get_bool(ID_is_bridge_method)); + } + } + } + } +}