From c84cf21e8a1a972221e5e0b13393d927474ae8d8 Mon Sep 17 00:00:00 2001 From: thk123 Date: Thu, 1 Mar 2018 14:52:28 +0000 Subject: [PATCH 1/9] Made member_type_lazy return type match what the method returns Tidied up some accesses that were previously using direct irep access. --- .../java_bytecode_convert_method.cpp | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 0e98aeebfe6..34059e397b5 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -256,11 +256,11 @@ const exprt java_bytecode_convert_methodt::variable( /// message handler to collect warnings /// \return /// the constructed member type -typet member_type_lazy(const std::string &descriptor, - const optionalt &signature, - const std::string &class_name, - const std::string &method_name, - message_handlert &message_handler) +code_typet member_type_lazy(const std::string &descriptor, + const optionalt &signature, + const std::string &class_name, + const std::string &method_name, + message_handlert &message_handler) { // In order to construct the method type, we can either use signature or // descriptor. Since only signature contains the generics info, we want to @@ -285,7 +285,7 @@ typet member_type_lazy(const std::string &descriptor, if(to_code_type(member_type_from_signature).parameters().size()== to_code_type(member_type_from_descriptor).parameters().size()) { - return member_type_from_signature; + return to_code_type(member_type_from_signature); } else { @@ -303,7 +303,7 @@ typet member_type_lazy(const std::string &descriptor, << descriptor << message.eom; } } - return member_type_from_descriptor; + return to_code_type(member_type_from_descriptor); } /// This creates a method symbol in the symtab, but doesn't actually perform @@ -324,7 +324,7 @@ void java_bytecode_convert_method_lazy( { symbolt method_symbol; - typet member_type=member_type_lazy( + code_typet member_type=member_type_lazy( m.descriptor, m.signature, id2string(class_symbol.name), @@ -337,13 +337,13 @@ void java_bytecode_convert_method_lazy( method_symbol.location=m.source_location; method_symbol.location.set_function(method_identifier); if(m.is_public) - member_type.set(ID_access, ID_public); + member_type.set_access(ID_public); else if(m.is_protected) - member_type.set(ID_access, ID_protected); + member_type.set_access(ID_protected); else if(m.is_private) - member_type.set(ID_access, ID_private); + member_type.set_access(ID_private); else - member_type.set(ID_access, ID_default); + member_type.set_access(ID_default); if(method_symbol.base_name=="") { @@ -360,8 +360,7 @@ void java_bytecode_convert_method_lazy( // do we need to add 'this' as a parameter? if(!m.is_static) { - code_typet &code_type=to_code_type(member_type); - code_typet::parameterst ¶meters=code_type.parameters(); + code_typet::parameterst ¶meters=member_type.parameters(); code_typet::parametert this_p; const reference_typet object_ref_type= java_reference_type(symbol_typet(class_symbol.name)); From b25301e8f5535cf579ff22ef02b3aa9992df3e5d Mon Sep 17 00:00:00 2001 From: thk123 Date: Thu, 1 Mar 2018 15:04:59 +0000 Subject: [PATCH 2/9] Remove redundant method and constructor setter --- .../java_bytecode_convert_method.cpp | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 34059e397b5..287babedb41 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -518,25 +518,12 @@ void java_bytecode_convert_methodt::convert( param_index==slots_for_parameters, "java_parameter_count and local computation must agree"); - const bool is_virtual=!m.is_static && !m.is_final; - - // Construct a methodt, which lives within the class type; this object is - // never used for anything useful and could be removed - class_typet::methodt method; - method.set_base_name(m.base_name); - method.set_name(method_identifier); - method.set(ID_abstract, m.is_abstract); - method.set(ID_is_virtual, is_virtual); - method.type()=member_type; - if(is_constructor(method)) - method.set(ID_constructor, true); - // Check the fields that can't change are valid INVARIANT( - method_symbol.name==method.get_name(), + method_symbol.name==method_identifier, "Name of method symbol shouldn't change"); INVARIANT( - method_symbol.base_name==method.get_base_name(), + method_symbol.base_name==m.base_name, "Base name of method symbol shouldn't change"); INVARIANT( method_symbol.module.empty(), @@ -550,16 +537,21 @@ void java_bytecode_convert_methodt::convert( // The pretty name of a constructor includes the base name of the class // instead of the internal method name "". For regular methods, it's // just the base name of the method. - if(method.get_base_name()=="") - method_symbol.pretty_name=id2string(class_symbol.pretty_name)+"."+ - id2string(class_symbol.base_name)+"()"; + if(method_symbol.base_name=="") + { + method_symbol.pretty_name = id2string(class_symbol.pretty_name) + "." + + id2string(class_symbol.base_name) + "()"; + INVARIANT( + member_type.get_bool(ID_constructor), + "Member type should have already been marked as a constructor"); + } else - method_symbol.pretty_name=id2string(class_symbol.pretty_name)+"."+ - id2string(method.get_base_name())+"()"; + { + method_symbol.pretty_name = id2string(class_symbol.pretty_name) + "." + + id2string(m.base_name) + "()"; + } method_symbol.type=member_type; - if(is_constructor(method)) - method_symbol.type.set(ID_constructor, true); current_method=method_symbol.name; method_has_this=code_type.has_this(); From e5ff31f2308882de60f275f15120d1295aab3731 Mon Sep 17 00:00:00 2001 From: thk123 Date: Fri, 2 Mar 2018 11:06:36 +0000 Subject: [PATCH 3/9] Replace checks for with a call to is_constructor Removed redundant is_constructor that checked for both constructors and static initalisers. --- .../java_bytecode_convert_method.cpp | 16 +++++----------- .../java_bytecode_convert_method_class.h | 4 ---- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 287babedb41..ff36658dc75 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -120,13 +120,9 @@ static bool operator==(const irep_idt &what, const patternt &pattern) return pattern==what; } -// name contains or -bool java_bytecode_convert_methodt::is_constructor( - const class_typet::methodt &method) +static bool is_constructor(const irep_idt &method_name) { - const std::string &name(id2string(method.get_name())); - const std::string::size_type &npos(std::string::npos); - return npos!=name.find("") || npos!=name.find(""); + return id2string(method_name).find("") != std::string::npos; } exprt::operandst java_bytecode_convert_methodt::pop(std::size_t n) @@ -345,7 +341,7 @@ void java_bytecode_convert_method_lazy( else member_type.set_access(ID_default); - if(method_symbol.base_name=="") + if(is_constructor(method_symbol.base_name)) { method_symbol.pretty_name= id2string(class_symbol.pretty_name)+"."+ @@ -537,7 +533,7 @@ void java_bytecode_convert_methodt::convert( // The pretty name of a constructor includes the base name of the class // instead of the internal method name "". For regular methods, it's // just the base name of the method. - if(method_symbol.base_name=="") + if(is_constructor(method_symbol.base_name)) { method_symbol.pretty_name = id2string(class_symbol.pretty_name) + "." + id2string(class_symbol.base_name) + "()"; @@ -1271,9 +1267,7 @@ codet java_bytecode_convert_methodt::convert_instructions( // constructors. if(statement=="invokespecial") { - if( - id2string(arg0.get(ID_identifier)).find("") != - std::string::npos) + if(is_constructor(arg0.get(ID_identifier))) { if(needed_lazy_methods) needed_lazy_methods->add_needed_class(classname); diff --git a/src/java_bytecode/java_bytecode_convert_method_class.h b/src/java_bytecode/java_bytecode_convert_method_class.h index b7ea7d0748e..930bc62ae62 100644 --- a/src/java_bytecode/java_bytecode_convert_method_class.h +++ b/src/java_bytecode/java_bytecode_convert_method_class.h @@ -161,10 +161,6 @@ class java_bytecode_convert_methodt:public messaget void pop_residue(std::size_t n); void push(const exprt::operandst &o); - /// Determines whether the `method` is a constructor or a static initializer, - /// by checking whether its name equals either or - bool is_constructor(const class_typet::methodt &method); - /// Returns true iff the slot index of the local variable of a method (coming /// from the LVT) is a parameter of that method. Assumes that /// `slots_for_parameters` is initialized upon call. From e8cbf903f843aabefd3bd390b22ea6bac2b5c05b Mon Sep 17 00:00:00 2001 From: thk123 Date: Mon, 5 Mar 2018 18:05:54 +0000 Subject: [PATCH 4/9] Adding wrappers around whether a code_type is a constructor --- src/java_bytecode/java_bytecode_convert_method.cpp | 6 +++--- src/util/std_types.h | 10 ++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index ff36658dc75..ce9e73093b4 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -346,7 +346,7 @@ void java_bytecode_convert_method_lazy( method_symbol.pretty_name= id2string(class_symbol.pretty_name)+"."+ id2string(class_symbol.base_name)+"()"; - member_type.set(ID_constructor, true); + member_type.set_is_constructor(); } else method_symbol.pretty_name= @@ -538,7 +538,7 @@ void java_bytecode_convert_methodt::convert( method_symbol.pretty_name = id2string(class_symbol.pretty_name) + "." + id2string(class_symbol.base_name) + "()"; INVARIANT( - member_type.get_bool(ID_constructor), + code_type.get_is_constructor(), "Member type should have already been marked as a constructor"); } else @@ -1271,7 +1271,7 @@ codet java_bytecode_convert_methodt::convert_instructions( { if(needed_lazy_methods) needed_lazy_methods->add_needed_class(classname); - code_type.set(ID_constructor, true); + code_type.set_is_constructor(); } else code_type.set(ID_java_super_method_call, true); diff --git a/src/util/std_types.h b/src/util/std_types.h index 58bbf5d921b..cc7b4706d41 100644 --- a/src/util/std_types.h +++ b/src/util/std_types.h @@ -889,6 +889,16 @@ class code_typet:public typet return set(ID_access, access); } + bool get_is_constructor() const + { + return get_bool(ID_constructor); + } + + void set_is_constructor() + { + set(ID_constructor, true); + } + // this produces the list of parameter identifiers std::vector parameter_identifiers() const { From 6edaaa0609c2b7a86c88e4af3a6dd8613663f6f8 Mon Sep 17 00:00:00 2001 From: thk123 Date: Mon, 5 Mar 2018 18:07:57 +0000 Subject: [PATCH 5/9] Remove the uncasted member_type so all references use the correct version --- src/java_bytecode/java_bytecode_convert_method.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index ce9e73093b4..859510ee622 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -385,9 +385,9 @@ void java_bytecode_convert_methodt::convert( // Obtain a std::vector of code_typet::parametert objects from the // (function) type of the symbol - typet member_type=method_symbol.type; - member_type.set(ID_C_class, class_symbol.name); - code_typet &code_type=to_code_type(member_type); + + code_typet code_type=to_code_type(method_symbol.type); + code_type.set(ID_C_class, class_symbol.name); method_return_type=code_type.return_type(); code_typet::parameterst ¶meters=code_type.parameters(); @@ -547,7 +547,7 @@ void java_bytecode_convert_methodt::convert( id2string(m.base_name) + "()"; } - method_symbol.type=member_type; + method_symbol.type=code_type; current_method=method_symbol.name; method_has_this=code_type.has_this(); From 80a439d043683daf95903a04bee82dd2e2d8554a Mon Sep 17 00:00:00 2001 From: thk123 Date: Tue, 6 Mar 2018 10:17:19 +0000 Subject: [PATCH 6/9] Apply clang-format --- .../java_bytecode_convert_method.cpp | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 859510ee622..aba287e50da 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -252,11 +252,12 @@ const exprt java_bytecode_convert_methodt::variable( /// message handler to collect warnings /// \return /// the constructed member type -code_typet member_type_lazy(const std::string &descriptor, - const optionalt &signature, - const std::string &class_name, - const std::string &method_name, - message_handlert &message_handler) +code_typet member_type_lazy( + const std::string &descriptor, + const optionalt &signature, + const std::string &class_name, + const std::string &method_name, + message_handlert &message_handler) { // In order to construct the method type, we can either use signature or // descriptor. Since only signature contains the generics info, we want to @@ -320,7 +321,7 @@ void java_bytecode_convert_method_lazy( { symbolt method_symbol; - code_typet member_type=member_type_lazy( + code_typet member_type = member_type_lazy( m.descriptor, m.signature, id2string(class_symbol.name), @@ -356,7 +357,7 @@ void java_bytecode_convert_method_lazy( // do we need to add 'this' as a parameter? if(!m.is_static) { - code_typet::parameterst ¶meters=member_type.parameters(); + code_typet::parameterst ¶meters = member_type.parameters(); code_typet::parametert this_p; const reference_typet object_ref_type= java_reference_type(symbol_typet(class_symbol.name)); @@ -386,7 +387,7 @@ void java_bytecode_convert_methodt::convert( // Obtain a std::vector of code_typet::parametert objects from the // (function) type of the symbol - code_typet code_type=to_code_type(method_symbol.type); + code_typet code_type = to_code_type(method_symbol.type); code_type.set(ID_C_class, class_symbol.name); method_return_type=code_type.return_type(); code_typet::parameterst ¶meters=code_type.parameters(); @@ -516,10 +517,10 @@ void java_bytecode_convert_methodt::convert( // Check the fields that can't change are valid INVARIANT( - method_symbol.name==method_identifier, + method_symbol.name == method_identifier, "Name of method symbol shouldn't change"); INVARIANT( - method_symbol.base_name==m.base_name, + method_symbol.base_name == m.base_name, "Base name of method symbol shouldn't change"); INVARIANT( method_symbol.module.empty(), @@ -543,11 +544,11 @@ void java_bytecode_convert_methodt::convert( } else { - method_symbol.pretty_name = id2string(class_symbol.pretty_name) + "." + - id2string(m.base_name) + "()"; + method_symbol.pretty_name = + id2string(class_symbol.pretty_name) + "." + id2string(m.base_name) + "()"; } - method_symbol.type=code_type; + method_symbol.type = code_type; current_method=method_symbol.name; method_has_this=code_type.has_this(); From 44153b71361e7e0ac5d53ef28cd106010301ea88 Mon Sep 17 00:00:00 2001 From: thk123 Date: Tue, 6 Mar 2018 13:14:10 +0000 Subject: [PATCH 7/9] Adding unit tests verifying initalizsers are correctly labelled --- .../ClassUsingOpaqueStaticConstructor.class | Bin 0 -> 638 bytes .../ClassWithConstructors.class | Bin 0 -> 512 bytes .../ClassWithStaticConstructor.class | Bin 0 -> 782 bytes .../ClassWithoutConstructors.class | Bin 0 -> 292 bytes .../DummyClassLoadingOpaqueClass.class | Bin 0 -> 643 bytes .../ExampleConstructors.java | 93 +++++++ ...ticClassUsingOpaqueStaticConstructor.class | Bin 0 -> 686 bytes .../convert_initalizers.cpp | 250 ++++++++++++++++++ 8 files changed, 343 insertions(+) create mode 100644 unit/java_bytecode/java_bytecode_convert_method/ClassUsingOpaqueStaticConstructor.class create mode 100644 unit/java_bytecode/java_bytecode_convert_method/ClassWithConstructors.class create mode 100644 unit/java_bytecode/java_bytecode_convert_method/ClassWithStaticConstructor.class create mode 100644 unit/java_bytecode/java_bytecode_convert_method/ClassWithoutConstructors.class create mode 100644 unit/java_bytecode/java_bytecode_convert_method/DummyClassLoadingOpaqueClass.class create mode 100644 unit/java_bytecode/java_bytecode_convert_method/ExampleConstructors.java create mode 100644 unit/java_bytecode/java_bytecode_convert_method/StaticClassUsingOpaqueStaticConstructor.class create mode 100644 unit/java_bytecode/java_bytecode_convert_method/convert_initalizers.cpp diff --git a/unit/java_bytecode/java_bytecode_convert_method/ClassUsingOpaqueStaticConstructor.class b/unit/java_bytecode/java_bytecode_convert_method/ClassUsingOpaqueStaticConstructor.class new file mode 100644 index 0000000000000000000000000000000000000000..a2f363c7207e2ab8bf3f63f69239f44707e53e2c GIT binary patch literal 638 zcmaixNlzO=5QSeGV`F=Q!GS;^VHpS*6X8ol78WV75-E~}4=nfg(1Awd8D|!hzXj4L zQV#rp{3w)HLljxLaOm$5@)GPcTSDO87%9oWQPn~w_W>uBNAXwqR4nQtaCfhVnv?v=jQZC?i$?Oy-N zc*)*qhs^$K=WJ=;1~xfV7;A2wDHJ>5xlyQhZD5YlLEl6ty6>~n=!Ty5&vaxZ|6433 zmo`>d>vnt{$EUFkE_y@#JvGOPPOR4ngE)y&F9{>r;W$hq&wR0R-TdbtdNB0ONK3pU zi#wRd^D?#_OkvtVL-15EgINd91ap{GSbfw|Ve0>vP^dlZmk(ow?_KA&m3ZhzLJV`I zXRfr(mCm`+oXQ`OJ;?=TDGH2$cIzip>lTF!W0YcsaY`venKF@~LaAn`QJf4LW__Hp zr^;@yeexi}MIgV9xNnE6!GTL?|G5OA`Evp6pukUPPXYX7a9NhvJ77($-QE-EF-wRl<{e zViNUSTjQ&TALVGAsyR=^L;FM#marTlKucih&o_$@p&cPaD?$ftfwljyh(15fHUTr#o-K(NXfaO@FOE(#}=*y0)V-2^tRlvc&{2jU*V7)m-?JK;u kv^j+zOi`b)hV?C+?-h!G?tHQiM|3IPqpZL>^EGVz1X3cFd;kCd literal 0 HcmV?d00001 diff --git a/unit/java_bytecode/java_bytecode_convert_method/ClassWithoutConstructors.class b/unit/java_bytecode/java_bytecode_convert_method/ClassWithoutConstructors.class new file mode 100644 index 0000000000000000000000000000000000000000..995e9d9b66ee8a9b9fd268acdf0db72a17bda5f5 GIT binary patch literal 292 zcmZ`!u};H441I3X1kymOPKb#S7@CC*)FmoY)DEr6d@+jq(#h_xffBKa@KAuX_unX ztc*%i3%wFnh5lEJ{8~A}Wm#z9+>`Qa)B3_R&fB*3#=3h#x-hM+<)aE$E~al{yVLTo zXS@-wB1428&;L6_7zSIeMe~x+tBtHZuF&C6LJ%kKGsetv#-Q|W-$8pO9VA@igV@Ij Q^XzEADN^nT{evs}0n#u*=Kufz literal 0 HcmV?d00001 diff --git a/unit/java_bytecode/java_bytecode_convert_method/DummyClassLoadingOpaqueClass.class b/unit/java_bytecode/java_bytecode_convert_method/DummyClassLoadingOpaqueClass.class new file mode 100644 index 0000000000000000000000000000000000000000..375b67e30ced65485eed7fcb038eeb38973b4d4d GIT binary patch literal 643 zcmaJ;T~8BH6r9^`yR$9oWR|mGQ`AZ}cc4(+$#4M+Z8y(*Gu%;@IX2ycCCb%+j+0!ab)~7$&0KEi!{q0h@A%y zQwo!pR`hTU*FD@2m=m~(c@MV)7BH`{@W0FooqxB)GUR&XQG9tG>lJ=|;&n{04(^{r zeL?N*IqE?L=V^t;Mup}hr-D0dRG1hxE3}60M~Z8hCa$7I+=PQI8v5v98?)Hqs=Mgn z8CLKdeY_+Oy!v$ruA{?H0afo^u#`=_zU2& JF4C)p-Veluf6D*> literal 0 HcmV?d00001 diff --git a/unit/java_bytecode/java_bytecode_convert_method/ExampleConstructors.java b/unit/java_bytecode/java_bytecode_convert_method/ExampleConstructors.java new file mode 100644 index 00000000000..bef886f1cd2 --- /dev/null +++ b/unit/java_bytecode/java_bytecode_convert_method/ExampleConstructors.java @@ -0,0 +1,93 @@ +class ClassWithConstructors { + public ClassWithConstructors() { + + } + + public ClassWithConstructors(int primitiveParam, Object referenceParam, OpaqueClass opaqueParam) { + + } +} + +class ClassWithoutConstructors { + +} + +class ClassWithStaticConstructor { + static int primitiveA = 4; + static int primitiveB; + static int primitiveC; + static Object referenceA = new Object(); + static Object referenceB; + static Object referenceC; + + static { + primitiveB = 5; + referenceB = new Object(); + } + + public ClassWithStaticConstructor() { + + } + + public ClassWithStaticConstructor(int primitiveParam, Object referenceParam, OpaqueClass opaqueParam) { + + } +} + +class StaticClassUsingOpaqueStaticConstructor { + static int primitiveA = OpaqueClass.primitiveA; + static int primitiveB = OpaqueClass.primitiveB; + static int primitiveC = OpaqueClass.primitiveC; + static Object referenceA = OpaqueClass.referenceA; + static Object referenceB = OpaqueClass.referenceB; + static Object referenceC = OpaqueClass.referenceC; +} + +class ClassUsingOpaqueStaticConstructor { + int primitiveA; + int primitiveB; + int primitiveC; + Object referenceA; + Object referenceB; + Object referenceC; + + public ClassUsingOpaqueStaticConstructor(){ + primitiveA = OpaqueClass.primitiveA; + primitiveB = OpaqueClass.primitiveB; + primitiveC = OpaqueClass.primitiveC; + referenceA = OpaqueClass.referenceA; + referenceB = OpaqueClass.referenceB; + referenceC = OpaqueClass.referenceC; + } +} + +class DummyClassLoadingOpaqueClass { + DummyClassLoadingOpaqueClass() { + OpaqueClass o = new OpaqueClass(); + int primitiveA = OpaqueClass.primitiveA; + int primitiveB = OpaqueClass.primitiveB; + int primitiveC = OpaqueClass.primitiveC; + Object referenceA = OpaqueClass.referenceA; + Object referenceB = OpaqueClass.referenceB; + Object referenceC = OpaqueClass.referenceC; + + } +} + +class OpaqueClass { + static int primitiveA = 4; + static int primitiveB; + static int primitiveC; + static Object referenceA = new Object(); + static Object referenceB; + static Object referenceC; + + static { + primitiveB = 5; + referenceB = new Object(); + } + + public OpaqueClass() { + // opaque constructor + } +} diff --git a/unit/java_bytecode/java_bytecode_convert_method/StaticClassUsingOpaqueStaticConstructor.class b/unit/java_bytecode/java_bytecode_convert_method/StaticClassUsingOpaqueStaticConstructor.class new file mode 100644 index 0000000000000000000000000000000000000000..de04619155ca2af73a53bd9a73750ef2043edf62 GIT binary patch literal 686 zcma)3T~8W86g>k73vPwdQt_jfx ztOzXFtn30h1?&oxCV?L7NZ+et0dc;VI9UvO6a?x<1UkT)T{8ex=77g!wet#3pI;sQ~Y>MUjCI z^X7~61Zc*{B*@0dC0L4)Pf& + +#include + +#include +#include + +#include + +#include +#include + +struct test_datat +{ + symbol_tablet symbol_table; + std::string constructor_descriptor; +}; + +/// Verify that a given descriptor is marked as a constructor in the symbol +/// table +/// \param test_data The data to run the test on +void require_is_constructor(const test_datat &test_data) +{ + + const symbolt &constructor = + test_data.symbol_table.lookup_ref(test_data.constructor_descriptor); + THEN("The constructor should be marked as a constructor") + { + code_typet constructor_type = require_type::require_code(constructor.type); + REQUIRE(constructor_type.get_is_constructor()); + } +} + +/// Verify that a given descriptor is not marked as a constructor in the symbol +/// table +/// \param test_data The data to run the test on +void require_is_static_initalizer(const test_datat &test_data) +{ + const symbolt &constructor = + test_data.symbol_table.lookup_ref(test_data.constructor_descriptor); + THEN("The constructor should be marked as a constructor") + { + code_typet constructor_type = require_type::require_code(constructor.type); + REQUIRE_FALSE(constructor_type.get_is_constructor()); + } +} + +SCENARIO( + "java_bytecode_convert_initalizers", + "[core][java_bytecode][java_bytecode_convert_method]") +{ + GIVEN("A class with some constructors") + { + const symbol_tablet symbol_table = load_java_class( + "ClassWithConstructors", "./java_bytecode/java_bytecode_convert_method"); + std::string base_constructor_name = "java::ClassWithConstructors."; + WHEN("Looking at the parameterless constructor") + { + require_is_constructor([&]() { + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + WHEN("Looking at the parametered constructor") + { + require_is_constructor([&]() { + test_datat data; + data.constructor_descriptor = + base_constructor_name + ":(ILjava/lang/Object;LOpaqueClass;)V"; + data.symbol_table = symbol_table; + return data; + }()); + } + } + GIVEN("A class without any constructors") + { + const symbol_tablet symbol_table = load_java_class( + "ClassWithoutConstructors", + "./java_bytecode/java_bytecode_convert_method"); + std::string base_constructor_name = "java::ClassWithoutConstructors."; + WHEN("Looking at the default constructor") + { + require_is_constructor([&]() { + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + } + GIVEN("A class with both constructors and static initalisers") + { + const symbol_tablet symbol_table = load_java_class( + "ClassWithStaticConstructor", + "./java_bytecode/java_bytecode_convert_method"); + std::string base_class_name = "java::ClassWithStaticConstructor."; + std::string base_constructor_name = base_class_name + ""; + WHEN("Looking at the parameterless constructor") + { + require_is_constructor([&]() { + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + WHEN("Looking at the parametered constructor") + { + require_is_constructor([&]() { + test_datat data; + data.constructor_descriptor = + base_constructor_name + ":(ILjava/lang/Object;LOpaqueClass;)V"; + data.symbol_table = symbol_table; + return data; + }()); + } + WHEN("Looking at the static initalizer") + { + THEN("The static init should not be marked as a constructor") + { + require_is_static_initalizer([&]() { + test_datat data; + data.constructor_descriptor = base_class_name + ":()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + } + } + GIVEN("A class with a static initalizer calling an opaque static initalizer") + { + const symbol_tablet symbol_table = load_java_class( + "StaticClassUsingOpaqueStaticConstructor", + "./java_bytecode/java_bytecode_convert_method"); + + std::string base_class_name = + "java::StaticClassUsingOpaqueStaticConstructor."; + std::string base_constructor_name = base_class_name + ""; + + WHEN("Looking at the default constructor") + { + require_is_constructor([&]() { + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + WHEN("Looking at the static initalizer") + { + THEN("The static init should not be marked as a constructor") + { + require_is_static_initalizer([&]() { + test_datat data; + data.constructor_descriptor = base_class_name + ":()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + } + } + GIVEN("A class with a constructor calling opaque static initalizer") + { + const symbol_tablet symbol_table = load_java_class( + "ClassUsingOpaqueStaticConstructor", + "./java_bytecode/java_bytecode_convert_method"); + + std::string base_class_name = "java::ClassUsingOpaqueStaticConstructor."; + std::string base_constructor_name = base_class_name + ""; + + WHEN("Looking at the parameterless constructor") + { + require_is_constructor([&]() { + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + WHEN("Looking at the static initalizer for the opaque class") + { + THEN("The static init should not be marked as a constructor") + { + require_is_static_initalizer([&]() { + test_datat data; + data.constructor_descriptor = "java::OpaqueClass.:()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + } + } + GIVEN("A class with a constructor calling opaque constructor") + { + const symbol_tablet symbol_table = load_java_class( + "DummyClassLoadingOpaqueClass", + "./java_bytecode/java_bytecode_convert_method"); + + std::string base_class_name = "java::DummyClassLoadingOpaqueClass."; + std::string base_constructor_name = base_class_name + ""; + + const symbolt &opaque_class_symbol = + symbol_table.lookup_ref("java::OpaqueClass"); + REQUIRE(opaque_class_symbol.type.get_bool(ID_incomplete_class)); + + WHEN("Looking at the parameterless constructor") + { + require_is_constructor([&]() { + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + WHEN("Looking at the static initalizer for the opaque class") + { + THEN("The static init should not be marked as a constructor") + { + require_is_static_initalizer([&]() { + test_datat data; + data.constructor_descriptor = "java::OpaqueClass.:()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + } + WHEN("Looking at the constructor for the opaque class") + { + THEN("The static init should not be marked as a constructor") + { + require_is_constructor([&]() { + test_datat data; + data.constructor_descriptor = "java::OpaqueClass.:()V"; + data.symbol_table = symbol_table; + return data; + }()); + } + } + } +} From bf86af421cd52555e5c10a76cde071d20cd30496 Mon Sep 17 00:00:00 2001 From: thk123 Date: Thu, 8 Mar 2018 17:15:07 +0000 Subject: [PATCH 8/9] Correcting review comments --- src/java_bytecode/java_bytecode_convert_method.cpp | 5 ++--- .../java_bytecode_convert_method/convert_initalizers.cpp | 8 +++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index aba287e50da..366674e85dc 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -386,7 +386,6 @@ void java_bytecode_convert_methodt::convert( // Obtain a std::vector of code_typet::parametert objects from the // (function) type of the symbol - code_typet code_type = to_code_type(method_symbol.type); code_type.set(ID_C_class, class_symbol.name); method_return_type=code_type.return_type(); @@ -544,8 +543,8 @@ void java_bytecode_convert_methodt::convert( } else { - method_symbol.pretty_name = - id2string(class_symbol.pretty_name) + "." + id2string(m.base_name) + "()"; + method_symbol.pretty_name = id2string(class_symbol.pretty_name) + "." + + id2string(method_symbol.base_name) + "()"; } method_symbol.type = code_type; diff --git a/unit/java_bytecode/java_bytecode_convert_method/convert_initalizers.cpp b/unit/java_bytecode/java_bytecode_convert_method/convert_initalizers.cpp index 53e55fe436b..eee5fffa76e 100644 --- a/unit/java_bytecode/java_bytecode_convert_method/convert_initalizers.cpp +++ b/unit/java_bytecode/java_bytecode_convert_method/convert_initalizers.cpp @@ -1,8 +1,8 @@ /*******************************************************************\ - Module: Unit tests for converting abstract classes + Module: Unit tests for converting constructors and static initializers - Author: DiffBlue Limited. All rights reserved. + Author: DiffBlue Limited. \*******************************************************************/ @@ -42,8 +42,10 @@ void require_is_constructor(const test_datat &test_data) /// Verify that a given descriptor is not marked as a constructor in the symbol /// table /// \param test_data The data to run the test on -void require_is_static_initalizer(const test_datat &test_data) +void require_is_static_initializer(const test_datat &test_data) { + REQUIRE( + test_data.constructor_descriptor.find("") != std::string::npos); const symbolt &constructor = test_data.symbol_table.lookup_ref(test_data.constructor_descriptor); THEN("The constructor should be marked as a constructor") From 1a89e97e237b241ec1b879ff4a9a883624b0bded Mon Sep 17 00:00:00 2001 From: thk123 Date: Thu, 8 Mar 2018 17:15:20 +0000 Subject: [PATCH 9/9] Remove lambda in favour of direct construction --- .../convert_initalizers.cpp | 135 +++++++----------- 1 file changed, 54 insertions(+), 81 deletions(-) diff --git a/unit/java_bytecode/java_bytecode_convert_method/convert_initalizers.cpp b/unit/java_bytecode/java_bytecode_convert_method/convert_initalizers.cpp index eee5fffa76e..57be6d8a250 100644 --- a/unit/java_bytecode/java_bytecode_convert_method/convert_initalizers.cpp +++ b/unit/java_bytecode/java_bytecode_convert_method/convert_initalizers.cpp @@ -29,7 +29,6 @@ struct test_datat /// \param test_data The data to run the test on void require_is_constructor(const test_datat &test_data) { - const symbolt &constructor = test_data.symbol_table.lookup_ref(test_data.constructor_descriptor); THEN("The constructor should be marked as a constructor") @@ -66,22 +65,18 @@ SCENARIO( std::string base_constructor_name = "java::ClassWithConstructors."; WHEN("Looking at the parameterless constructor") { - require_is_constructor([&]() { - test_datat data; - data.constructor_descriptor = base_constructor_name + ":()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + require_is_constructor(data); } WHEN("Looking at the parametered constructor") { - require_is_constructor([&]() { - test_datat data; - data.constructor_descriptor = - base_constructor_name + ":(ILjava/lang/Object;LOpaqueClass;)V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = + base_constructor_name + ":(ILjava/lang/Object;LOpaqueClass;)V"; + data.symbol_table = symbol_table; + require_is_constructor(data); } } GIVEN("A class without any constructors") @@ -92,12 +87,10 @@ SCENARIO( std::string base_constructor_name = "java::ClassWithoutConstructors."; WHEN("Looking at the default constructor") { - require_is_constructor([&]() { - test_datat data; - data.constructor_descriptor = base_constructor_name + ":()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + require_is_constructor(data); } } GIVEN("A class with both constructors and static initalisers") @@ -109,33 +102,27 @@ SCENARIO( std::string base_constructor_name = base_class_name + ""; WHEN("Looking at the parameterless constructor") { - require_is_constructor([&]() { - test_datat data; - data.constructor_descriptor = base_constructor_name + ":()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + require_is_constructor(data); } WHEN("Looking at the parametered constructor") { - require_is_constructor([&]() { - test_datat data; - data.constructor_descriptor = - base_constructor_name + ":(ILjava/lang/Object;LOpaqueClass;)V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = + base_constructor_name + ":(ILjava/lang/Object;LOpaqueClass;)V"; + data.symbol_table = symbol_table; + require_is_constructor(data); } WHEN("Looking at the static initalizer") { THEN("The static init should not be marked as a constructor") { - require_is_static_initalizer([&]() { - test_datat data; - data.constructor_descriptor = base_class_name + ":()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = base_class_name + ":()V"; + data.symbol_table = symbol_table; + require_is_static_initializer(data); } } } @@ -151,23 +138,19 @@ SCENARIO( WHEN("Looking at the default constructor") { - require_is_constructor([&]() { - test_datat data; - data.constructor_descriptor = base_constructor_name + ":()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + require_is_constructor(data); } WHEN("Looking at the static initalizer") { THEN("The static init should not be marked as a constructor") { - require_is_static_initalizer([&]() { - test_datat data; - data.constructor_descriptor = base_class_name + ":()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = base_class_name + ":()V"; + data.symbol_table = symbol_table; + require_is_static_initializer(data); } } } @@ -182,23 +165,19 @@ SCENARIO( WHEN("Looking at the parameterless constructor") { - require_is_constructor([&]() { - test_datat data; - data.constructor_descriptor = base_constructor_name + ":()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + require_is_constructor(data); } WHEN("Looking at the static initalizer for the opaque class") { THEN("The static init should not be marked as a constructor") { - require_is_static_initalizer([&]() { - test_datat data; - data.constructor_descriptor = "java::OpaqueClass.:()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = "java::OpaqueClass.:()V"; + data.symbol_table = symbol_table; + require_is_static_initializer(data); } } } @@ -217,35 +196,29 @@ SCENARIO( WHEN("Looking at the parameterless constructor") { - require_is_constructor([&]() { - test_datat data; - data.constructor_descriptor = base_constructor_name + ":()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = base_constructor_name + ":()V"; + data.symbol_table = symbol_table; + require_is_constructor(data); } WHEN("Looking at the static initalizer for the opaque class") { THEN("The static init should not be marked as a constructor") { - require_is_static_initalizer([&]() { - test_datat data; - data.constructor_descriptor = "java::OpaqueClass.:()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = "java::OpaqueClass.:()V"; + data.symbol_table = symbol_table; + require_is_static_initializer(data); } } WHEN("Looking at the constructor for the opaque class") { THEN("The static init should not be marked as a constructor") { - require_is_constructor([&]() { - test_datat data; - data.constructor_descriptor = "java::OpaqueClass.:()V"; - data.symbol_table = symbol_table; - return data; - }()); + test_datat data; + data.constructor_descriptor = "java::OpaqueClass.:()V"; + data.symbol_table = symbol_table; + require_is_constructor(data); } } }