From fc83526e3fe9a203d330c4604c1028cddd7addba Mon Sep 17 00:00:00 2001 From: svorenova Date: Tue, 20 Mar 2018 16:24:35 +0000 Subject: [PATCH 1/8] Ignore generic arguments for mocked and unsupported generic classes Given - a class extending/implementing a generic class/interface, - a generic pointer type, if the struct symbol for the superclass/interface/pointer subtype is either incomplete (mocked) or is not generic (e.g. because its signature has an unsupported form) ignore the generic arguments. --- ...eric_parameter_specialization_map_keys.cpp | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/java_bytecode/generic_parameter_specialization_map_keys.cpp b/src/java_bytecode/generic_parameter_specialization_map_keys.cpp index 45f4b86c392..e36c5853e8e 100644 --- a/src/java_bytecode/generic_parameter_specialization_map_keys.cpp +++ b/src/java_bytecode/generic_parameter_specialization_map_keys.cpp @@ -99,15 +99,17 @@ const void generic_parameter_specialization_map_keyst::insert_pairs_for_pointer( pointer_type.subtype().get(ID_identifier) == pointer_subtype_struct.get(ID_name)); - const java_generic_typet &generic_pointer = - to_java_generic_type(pointer_type); - // If the pointer points to an incomplete class, don't treat the generics - if(!pointer_subtype_struct.get_bool(ID_incomplete_class)) + // TODO TG-1996 should treat generic incomplete (mocked) classes + // Also do not treat generics is the class is not marked generic or + // implicitly generic (this may be due to unsupported class signature) + if( + !pointer_subtype_struct.get_bool(ID_incomplete_class) && + (is_java_generic_class_type(pointer_subtype_struct) || + is_java_implicitly_generic_class_type(pointer_subtype_struct))) { - PRECONDITION( - is_java_generic_class_type(pointer_subtype_struct) || - is_java_implicitly_generic_class_type(pointer_subtype_struct)); + const java_generic_typet &generic_pointer = + to_java_generic_type(pointer_type); const std::vector &generic_parameters = get_all_generic_parameters(pointer_subtype_struct); @@ -135,14 +137,19 @@ const void generic_parameter_specialization_map_keyst::insert_pairs_for_symbol( const symbol_typet &symbol_type, const typet &symbol_struct) { - if(is_java_generic_symbol_type(symbol_type)) + // If the class is an incomplete class, don't treat the generics + // TODO TG-1996 should treat generic incomplete (mocked) classes + // Also do not treat generics is the class is not marked generic or + // implicitly generic (this may be due to unsupported class signature) + if( + is_java_generic_symbol_type(symbol_type) && + !symbol_struct.get_bool(ID_incomplete_class) && + (is_java_generic_class_type(symbol_struct) || + is_java_implicitly_generic_class_type(symbol_struct))) { - java_generic_symbol_typet generic_symbol = + const java_generic_symbol_typet &generic_symbol = to_java_generic_symbol_type(symbol_type); - PRECONDITION( - is_java_generic_class_type(symbol_struct) || - is_java_implicitly_generic_class_type(symbol_struct)); const std::vector &generic_parameters = get_all_generic_parameters(symbol_struct); From 51a5845647e8e1d64a9797a3138a14464177475d Mon Sep 17 00:00:00 2001 From: svorenova Date: Wed, 21 Mar 2018 11:38:27 +0000 Subject: [PATCH 2/8] Pull out common generic classes/interfaces for unit tests --- .../goto_program_generics/GenericBases.java | 30 ++++------------ ...s$GenericInnerOuter$Outer$InnerClass.class | Bin 810 -> 810 bytes ...enericFields$GenericInnerOuter$Outer.class | Bin 1000 -> 1000 bytes .../GenericFields$GenericInnerOuter.class | Bin 1137 -> 1137 bytes ...GenericFields$GenericMethodParameter.class | Bin 814 -> 784 bytes ...GenericMethodUninstantiatedParameter.class | Bin 820 -> 790 bytes ...ericFields$GenericRewriteParameter$A.class | Bin 871 -> 871 bytes ...enericFields$GenericRewriteParameter.class | Bin 1126 -> 1126 bytes .../GenericFields$MultipleGenericFields.class | Bin 796 -> 778 bytes .../GenericFields$NestedGenericFields.class | Bin 753 -> 729 bytes .../GenericFields$PairGenericField.class | Bin 759 -> 762 bytes .../GenericFields$SimpleGenericField.class | Bin 786 -> 768 bytes .../goto_program_generics/GenericFields.class | Bin 908 -> 908 bytes .../goto_program_generics/GenericFields.java | 32 +++++------------- .../goto_program_generics/GenericHelper.java | 25 ++++++++++++++ .../goto_program_generics/IWrapper.class | Bin 270 -> 315 bytes .../goto_program_generics/IntWrapper.class | Bin 273 -> 0 bytes .../InterfaceWrapper.class | Bin 249 -> 250 bytes .../goto_program_generics/PairWrapper.class | Bin 489 -> 492 bytes .../goto_program_generics/SimpleWrapper.class | Bin 527 -> 0 bytes .../SuperclassInnerInst$Inner.class | Bin 670 -> 670 bytes .../SuperclassInnerInst$InnerGen.class | Bin 788 -> 788 bytes .../SuperclassInnerInst.class | Bin 792 -> 792 bytes .../SuperclassInnerUninst$Inner.class | Bin 766 -> 766 bytes .../SuperclassInnerUninst$InnerGen.class | Bin 899 -> 901 bytes .../SuperclassInnerUninst$InnerThree.class | Bin 633 -> 633 bytes .../SuperclassInnerUninst.class | Bin 928 -> 928 bytes .../SuperclassInnerUninstTest.class | Bin 1109 -> 1103 bytes .../SuperclassInst.class | Bin 491 -> 491 bytes .../SuperclassInst2.class | Bin 455 -> 451 bytes .../SuperclassInst3.class | Bin 477 -> 473 bytes .../SuperclassMixed.class | Bin 675 -> 673 bytes .../SuperclassMixedTest.class | Bin 579 -> 579 bytes .../SuperclassUninst.class | Bin 592 -> 592 bytes .../SuperclassUninstTest.class | Bin 560 -> 560 bytes .../goto_program_generics/TwoWrapper.class | Bin 488 -> 0 bytes .../goto_program_generics/Wrapper.class | Bin 425 -> 509 bytes .../generic_bases_test.cpp | 20 +++++------ .../generic_parameters_test.cpp | 32 +++++++++--------- 39 files changed, 65 insertions(+), 74 deletions(-) create mode 100644 unit/goto-programs/goto_program_generics/GenericHelper.java delete mode 100644 unit/goto-programs/goto_program_generics/IntWrapper.class delete mode 100644 unit/goto-programs/goto_program_generics/SimpleWrapper.class delete mode 100644 unit/goto-programs/goto_program_generics/TwoWrapper.class diff --git a/unit/goto-programs/goto_program_generics/GenericBases.java b/unit/goto-programs/goto_program_generics/GenericBases.java index 65b5b2a5534..6200a0edf43 100644 --- a/unit/goto-programs/goto_program_generics/GenericBases.java +++ b/unit/goto-programs/goto_program_generics/GenericBases.java @@ -1,21 +1,3 @@ -// Helper classes -class Wrapper { - public T field; -} - -class IntWrapper { - public int i; -} - -class TwoWrapper { - public K first; - public V second; -} - -interface InterfaceWrapper { - public T method(T t); -} - // A class extending a generic class instantiated with a standard library class class SuperclassInst extends Wrapper { public void foo() { @@ -24,14 +6,14 @@ public void foo() { } // A class extending a generic class instantiated with a user-defined class -class SuperclassInst2 extends Wrapper { +class SuperclassInst2 extends Wrapper { public void foo() { this.field.i = 5; } } // A class extending an instantiated nested generic class -class SuperclassInst3 extends Wrapper> { +class SuperclassInst3 extends Wrapper> { public void foo() { this.field.field.i = 5; } @@ -54,7 +36,7 @@ public void foo() { // A generic class extending a generic class with both instantiated and // uninstantiated parameters -class SuperclassMixed extends TwoWrapper { +class SuperclassMixed extends PairWrapper { public void foo(U value) { this.first = value; this.second.i = 5; @@ -99,7 +81,7 @@ public void foo(U value) { } public Inner inner; - class InnerGen extends TwoWrapper { + class InnerGen extends PairWrapper { public void foo(U uvalue, T tvalue) { this.first = uvalue; this.second = tvalue; @@ -113,9 +95,9 @@ class InnerThree extends Inner { } class SuperclassInnerUninstTest { - SuperclassInnerUninst f; + SuperclassInnerUninst f; public void foo() { - IntWrapper x = new IntWrapper(); + IWrapper x = new IWrapper(); f.inner.foo(x); f.inner_gen.foo(x,true); f.inner_three.foo(x); diff --git a/unit/goto-programs/goto_program_generics/GenericFields$GenericInnerOuter$Outer$InnerClass.class b/unit/goto-programs/goto_program_generics/GenericFields$GenericInnerOuter$Outer$InnerClass.class index faa5d2304eaec2f269d4282cd741a113ac92364b..05209db86959bb69aec62f4d7692a9d1071d6875 100644 GIT binary patch delta 13 UcmZ3*wu)`TMJ7h0$(NWS03&4t)&Kwi delta 13 UcmZ3*wu)`TMJ7h4$(NWS03)>o<^TWy diff --git a/unit/goto-programs/goto_program_generics/GenericFields$GenericInnerOuter$Outer.class b/unit/goto-programs/goto_program_generics/GenericFields$GenericInnerOuter$Outer.class index fa60ef8a06ee872a4b255db9cc573a05e3a43425..32483eb9b8ae09728b399346fe854f36dbd4d86b 100644 GIT binary patch delta 21 ccmaFC{(^l&Ju{~T11EzegD8X5qCS(Y7?qeMG<+tfGR|jY ZpUllv&!{rFo5_z=je&lsZZ=Q8=RnlbP&m`^^y6aWDG%^lAG diff --git a/unit/goto-programs/goto_program_generics/GenericFields$GenericMethodUninstantiatedParameter.class b/unit/goto-programs/goto_program_generics/GenericFields$GenericMethodUninstantiatedParameter.class index 970da292bad69080e108b6fe7b9c8e0d9a68ba06..46c27ddbe617bfc1ce5efc6cea458e0ad0c831a5 100644 GIT binary patch delta 94 zcmdnOHjQlqC!;8jhEI4=VnIP_k+o(RBLia@BLk<;WGzNzIX;+#O-P8foi$KAI5Ryj rv81#pm61Vxav`I{$jn6enPCQoPbVAWw@W6+)aged?3l++lS delta 125 zcmbQnwuNm2C!?Z}hEH&2Zb43Jcu`_OL28k;W*8#_V;Lg@KU93O9HX*|2&y8RkPvG- zYeojn;LP;A#FEmYR7M8f$?=R5Y!I_1morXd=Y_KQn6enHCRZ|fu-Y)NG1yK%#uNYm D8<`}C diff --git a/unit/goto-programs/goto_program_generics/GenericFields$GenericRewriteParameter$A.class b/unit/goto-programs/goto_program_generics/GenericFields$GenericRewriteParameter$A.class index 1fa20e2c5f94ac83216544527dccd4b0bae6c758..e035d0adc4f3e5f9108772086b3bc076a503d265 100644 GIT binary patch delta 13 UcmaFP_MB}4A2XxdWPaud03j&@-~a#s delta 13 UcmaFP_MB}4A2VavWPaud03mq;@Bjb+ diff --git a/unit/goto-programs/goto_program_generics/GenericFields$GenericRewriteParameter.class b/unit/goto-programs/goto_program_generics/GenericFields$GenericRewriteParameter.class index 419f729c848bff656b513fffcbf19489a93296f8..45c2286ccc99854f1fbdbc5cd5a9fd8d82fddc02 100644 GIT binary patch delta 27 jcmaFH@r+}`LS{zS$%~kyIDHrd82lI{7y>4e8@G9@$WOipD=;M8Z}XE0!pV=$b2j!6dq DcwG%$ diff --git a/unit/goto-programs/goto_program_generics/GenericFields$SimpleGenericField.class b/unit/goto-programs/goto_program_generics/GenericFields$SimpleGenericField.class index f29907667033e506c171d5622060fb364c3f9289..422893552173de1240c31a265c001cc4ec3172d8 100644 GIT binary patch delta 63 zcmbQl*1$HwQHs+iyeP4tAhpPvk%2QfGd(Y{q_ilNkwMgFV|oH3Bm3lYjGGx*CO0uf TbFwq=F>o+QGH_0Q#-sxPL%&d#B9jZ4qB+GG_!uM@BpD diff --git a/unit/goto-programs/goto_program_generics/GenericFields.class b/unit/goto-programs/goto_program_generics/GenericFields.class index b25d3be89ab454f3c11d1c0d86ee3442e70d9365..4414ff129687076d353c156c76a3719ef280f149 100644 GIT binary patch delta 13 UcmeBS?_uAd&dkU-S%WzR02qA(B>(^b delta 13 UcmeBS?_uAd&dew{S%WzR02s{!H2?qr diff --git a/unit/goto-programs/goto_program_generics/GenericFields.java b/unit/goto-programs/goto_program_generics/GenericFields.java index 92833f7743c..18441048806 100644 --- a/unit/goto-programs/goto_program_generics/GenericFields.java +++ b/unit/goto-programs/goto_program_generics/GenericFields.java @@ -1,24 +1,8 @@ -class SimpleWrapper { - public T field; - public T[] array_field; - - public int int_field; -} - -class IWrapper { - public int i; -} - -class PairWrapper { - public K key; - public V value; -} - public class GenericFields { IWrapper field; class SimpleGenericField { - SimpleWrapper field_input; + Wrapper field_input; public void foo() { field_input.field.i = 5; field_input.array_field = new IWrapper[2]; @@ -26,8 +10,8 @@ public void foo() { } class MultipleGenericFields { - SimpleWrapper field_input1; - SimpleWrapper field_input2; + Wrapper field_input1; + Wrapper field_input2; public void foo() { field_input1.field.i = 10; field_input2.field.i = 20; @@ -35,7 +19,7 @@ public void foo() { } class NestedGenericFields { - SimpleWrapper> field_input1; + Wrapper> field_input1; public void foo() { field_input1.field.field.i = 30; } @@ -44,19 +28,19 @@ public void foo() { class PairGenericField { PairWrapper field_input; public void foo() { - field_input.key.i = 40; - field_input.value.i = 50; + field_input.first.i = 40; + field_input.second.i = 50; } } class GenericMethodParameter { - public void foo(SimpleWrapper v) { + public void foo(Wrapper v) { v.field.i = 20; } } class GenericMethodUninstantiatedParameter { - public void foo_unspec(SimpleWrapper v) { + public void foo_unspec(Wrapper v) { v.int_field=10; } } diff --git a/unit/goto-programs/goto_program_generics/GenericHelper.java b/unit/goto-programs/goto_program_generics/GenericHelper.java new file mode 100644 index 00000000000..a871b5740cd --- /dev/null +++ b/unit/goto-programs/goto_program_generics/GenericHelper.java @@ -0,0 +1,25 @@ +// int wrapper +class IWrapper { + public int i; + public IWrapper(int ii) { + i = ii; + } +} + +// simple generic class +class Wrapper { + public T field; + public T[] array_field; + public int int_field; +} + +// generic class with two parameters +class PairWrapper { + public K first; + public V second; +} + +// simple generic interface +interface InterfaceWrapper { + public T method(T t); +} diff --git a/unit/goto-programs/goto_program_generics/IWrapper.class b/unit/goto-programs/goto_program_generics/IWrapper.class index 9374dd90e433f67b08f9580b79b4c520de7afd8d..ec21b63d591a4d65cd117b66ffe290fb3897fee5 100644 GIT binary patch delta 236 zcmXYqI|{;35Jm5MiHV6(t3;&}0o@BTKhUI7S<*UA!|LMF^IvP?b(& zt@7P*lF765V8JFh$)=KJsVais*ikNveYDzUDy=bs;3j|z(1Q7AXzo}$tfK!0FvADv b&W1pn(PDcDPPi;Q7MwtbS@WsODA4->v0Na? diff --git a/unit/goto-programs/goto_program_generics/IntWrapper.class b/unit/goto-programs/goto_program_generics/IntWrapper.class deleted file mode 100644 index 0ab2423e1075873be84834b8a78655f7613fc5ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 273 zcmYLDO;5s55S%Ujz*^KBL@hcU&}@xDX-+U@V_{bc<=}Cqlo(& z6AwF?ncdmU`SSe(V2ojm4tf##5e5X(GBZN>tc`A72%Y=Uir~LiYbNwEZTNk^&Dkzh zUWzl!szQ}3Wwq0Prr&(&nvi5O(|lO9+p&Ej#EWWg3!ZA18@#b$tBZ-MxqjTJgGvx0 zlB@p=q3;%Hsmy0O&o^8&xPvEk0ci;zLCfHhqPwEfb^`*zMWL`n{)V$Q9%w(s;;?&}a3nKw>4+(7m diff --git a/unit/goto-programs/goto_program_generics/PairWrapper.class b/unit/goto-programs/goto_program_generics/PairWrapper.class index 3684152febb684014d3099991d06120bb28d8941..f9ab0e804a9328dce800865b0755bcdb8815ea6b 100644 GIT binary patch delta 44 zcmaFK{DyggI2&tPW>Im;L}^WSw&K*}{JfNjUJuzkQgaGYizXW~HZlrM-pptQ09vRI A3jhEB delta 41 xcmaFE{E~TsI16)jYUM;(O*YoD#GKO9iM|in+%i*hQi>;=Fg7ysOy0(51^_364a5Kd diff --git a/unit/goto-programs/goto_program_generics/SimpleWrapper.class b/unit/goto-programs/goto_program_generics/SimpleWrapper.class deleted file mode 100644 index fbff730183d66c009f54cfc86694871820ab433c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 527 zcmZutO;5r=6r2Yw$d@1>ejYr62f27sLSjrXCPWWy@W8=r%Zf`%X_jKb&+=sA!5`p{ zGQL(Ysd(7knb~=7XW!@7`v-t?9Ose7K^BKu91+YXCA|@$+MkFQ(e{KtZr?i->4ukt zoTbLT2p3us(zeY?L1-^PJ1cB5XsF8FpgLOqcY3*>PF8iAu z`(iV6cT*zdt=U4mvZvxyH`13{xxHvy^RsAJMU=2jC?z5hDt`xw6Qp?L;KkpD$$N%b z3Ry;5$o=v>qXLS2N4&T>pJhf@d`60S`UZMskVb{~Oe_+17#DvGsG`QKo=|p~rB+Wi IuotuaZ-*Ll8~^|S diff --git a/unit/goto-programs/goto_program_generics/SuperclassInnerInst$Inner.class b/unit/goto-programs/goto_program_generics/SuperclassInnerInst$Inner.class index af39fafee64ff01ac3ef1b58ffe1fd1422799838..ee81c13a881cda91927cf1a4afdc8fc94fa0659f 100644 GIT binary patch delta 23 ecmbQoI*)aO6ceNQWN9WZR!asB2CK delta 23 ecmeyz`j2&kEfZt>WILuv)Z)M-Gh*3t{CdA4oE3qt5KPNFSUEe<`D>b>q+Ri5+F|%m$UdC)zZZJ!Ssgf~d W@-n74&M*d6hHwThhKR|$%w+%|78J(- delta 68 zcmZo=Z)V@Hh*4V0CdA4oE3qt5KPNFSUEe<`D>b>q+Ri7WJb&^&#%vZY5JQitk}+-a V3Z^*D3|D$&;B=1h2G+^P8C3vQI0gLx delta 23 ecmaFO{F-?~BO{~8#Go$q6a7JfVSq5$fxykbxRREog B40ssl( B5lsL9 delta 57 zcmcb~e3yB`WN{^*@S?R%&vIwVh8uVrEfzQDQ+sYLQJysI`yh zWMf7fbq-Ic7!QLAgDN8fe{d;KL2^!Faj|b^MQREo12;(H delta 92 zcmZ3;x|nqXC!?0JO{kSmR$^JAeokUuy1su>R%&vIwVh8$d470NVnIP_kxfXbwU1|B t$z&r&8x}4QqkvI?g$t-)@>Iq!M$5@>7^66?8CV%?7z7w>C;Kx60RT@>8!rF= diff --git a/unit/goto-programs/goto_program_generics/SuperclassMixedTest.class b/unit/goto-programs/goto_program_generics/SuperclassMixedTest.class index 550ff51a98e6092101bc4857952ac9654cb0fd32..3c22ba33d7d83d3e13361825247f40d82069ca5c 100644 GIT binary patch delta 47 wcmX@ia+qbqJw`^|$@dwZ6%84<8H^bC85kIN7#P8%0D~ZqW@Hcsl1vOD0O#HY1ONa4 delta 47 wcmX@ia+qbqJw`_R$@dwZ6`dKl8C)3n85kIN7#P8%0D~ZqW@Hcsl1vOD0Pgq(IsgCw diff --git a/unit/goto-programs/goto_program_generics/SuperclassUninst.class b/unit/goto-programs/goto_program_generics/SuperclassUninst.class index 8b30a539bbfe2b89b8017045570b7e62d5eed441..257e727dcd237a7d45d55cd6a309e4c4af5dfff7 100644 GIT binary patch delta 23 fcmcb>a)D*TN=8QU$*UOsStS`*8KfrvV+;ZST3QCl delta 23 fcmcb>a)D*TN=8P_$*UOsS+yBh8FVK9V+;ZSTx16S diff --git a/unit/goto-programs/goto_program_generics/SuperclassUninstTest.class b/unit/goto-programs/goto_program_generics/SuperclassUninstTest.class index a6c038edac5aa6808e6a6bf2ec43d7c0534e909f..1bfcdc483171280a6a62a7a0e5ec7bc95d99bf14 100644 GIT binary patch delta 47 ycmdnMvVmp8aYja&$tM`y6%`ox859`=7#J9M7#M-10D~Zd5RhhM5CM`*459$k#|4f6 delta 47 ycmdnMvVmp8aYjbH$tM`y6^$798H^bO7#J9M7#M-10D~Zd5RhhM5CM`*459$r;RVD1 diff --git a/unit/goto-programs/goto_program_generics/TwoWrapper.class b/unit/goto-programs/goto_program_generics/TwoWrapper.class deleted file mode 100644 index 7181bd114bab0da59579ba22aabab8b4f755a0fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 488 zcmZvYy-veG5QOLAI3dB1A3}hR5-3QM3M@;21Vt<;Vww8v9N{8kTW1@@V^JYd@Blm% zVlNnx5SrcnMx(pYe0;vW0~lhj2?PB)cIwz=Fz=+wa)z!u1kl(gPC#%{0e>7*+#?Txmg$l)` z)G<3(A{I)9=R6bHu`a|y6YJ#qjmXgc+Z6Uup-w@QI)F*DHm5pWYYW^UhJKN@Mb{Z^ mt(ZrzU@vqS*q~V}ZJTsk-v+eMCh9CHU7||))fRel+WrFaylII5 diff --git a/unit/goto-programs/goto_program_generics/Wrapper.class b/unit/goto-programs/goto_program_generics/Wrapper.class index ae6aa9aaf6196b41e19792e5e9875419e55721e4..496c09349cae3d1d676c35d9d5d1eb4eda41aa64 100644 GIT binary patch delta 245 zcmZ3<{Fhnu)W2Q(7#J8#7-YB@m>DG58Kl@5q$i3R3UDVD6(v^2r)8$*q%blFM^97` z5oL)E39)8m;LOY`fk`lWPITEKA>^K#ms*sW?2(#NkXoddl~|U@!@$eHH<_PNt)7{I zk%5JQ6-crHZDL|z2eLRAIN^LQAd8!U2Pnq~#6Vp@njgq=1kxZ8R;}#}j2nRrW(ENu m$p#kWVh{wfc_0cHgcyW@JP{NTQ6P^AsG1iERa8ARC`#3qUwPHfyHF6f?`ms*sW?37rXTCA6q zSeD4cz`?*d*_%k12F8s*1~UUU lkYoc3GBNM~**p*h47?0{KpsDehyaks1T|WaK?uwf1^_>h6J7uS diff --git a/unit/goto-programs/goto_program_generics/generic_bases_test.cpp b/unit/goto-programs/goto_program_generics/generic_bases_test.cpp index dd0e0deacb0..97dbd704513 100644 --- a/unit/goto-programs/goto_program_generics/generic_bases_test.cpp +++ b/unit/goto-programs/goto_program_generics/generic_bases_test.cpp @@ -86,7 +86,7 @@ SCENARIO( this_tmp_name, {"Wrapper"}, "field", - "java::IntWrapper", + "java::IWrapper", {"java::java.lang.Object"}, entry_point_code); } @@ -128,7 +128,7 @@ SCENARIO( wrapper_tmp_name, {}, "field", - "java::IntWrapper", + "java::IWrapper", {}, entry_point_code); } @@ -214,7 +214,7 @@ SCENARIO( { require_goto_statements::require_struct_component_assignment( f_tmp_name, - {"TwoWrapper"}, + {"PairWrapper"}, "first", "java::java.lang.Boolean", {"java::java.lang.Object"}, @@ -222,9 +222,9 @@ SCENARIO( require_goto_statements::require_struct_component_assignment( f_tmp_name, - {"TwoWrapper"}, + {"PairWrapper"}, "second", - "java::IntWrapper", + "java::IWrapper", {"java::java.lang.Object"}, entry_point_code); } @@ -354,7 +354,7 @@ SCENARIO( inner_tmp_name, {"Wrapper"}, "field", - "java::IntWrapper", + "java::IWrapper", {"java::java.lang.Object"}, entry_point_code); } @@ -373,14 +373,14 @@ SCENARIO( { require_goto_statements::require_struct_component_assignment( inner_gen_tmp_name, - {"TwoWrapper"}, + {"PairWrapper"}, "first", - "java::IntWrapper", + "java::IWrapper", {"java::java.lang.Object"}, entry_point_code); require_goto_statements::require_struct_component_assignment( inner_gen_tmp_name, - {"TwoWrapper"}, + {"PairWrapper"}, "second", "java::java.lang.Boolean", {"java::java.lang.Object"}, @@ -403,7 +403,7 @@ SCENARIO( inner_three_tmp_name, {"Wrapper"}, "field", - "java::IntWrapper", + "java::IWrapper", {"java::java.lang.Object"}, entry_point_code); } diff --git a/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp b/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp index 4f65efcef46..d7ba2eea9ab 100644 --- a/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp +++ b/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp @@ -39,14 +39,14 @@ SCENARIO( require_goto_statements::require_entry_point_argument_assignment( "this", entry_point_code); - THEN("Object 'this' has field 'field_input' of type SimpleWrapper") + THEN("Object 'this' has field 'field_input' of type Wrapper") { const auto &field_input_name = require_goto_statements::require_struct_component_assignment( tmp_object_name, {}, "field_input", - "java::SimpleWrapper", + "java::Wrapper", {}, entry_point_code); @@ -100,14 +100,14 @@ SCENARIO( require_goto_statements::require_entry_point_argument_assignment( "this", entry_point_code); - THEN("Object 'this' has field 'field_input1' of type SimpleWrapper") + THEN("Object 'this' has field 'field_input1' of type Wrapper") { const auto &field_input1_name = require_goto_statements::require_struct_component_assignment( tmp_object_name, {}, "field_input1", - "java::SimpleWrapper", + "java::Wrapper", {}, entry_point_code); @@ -123,14 +123,14 @@ SCENARIO( } } - THEN("Object 'this' has field 'field_input2' of type SimpleWrapper") + THEN("Object 'this' has field 'field_input2' of type Wrapper") { const auto &field_input2_name = require_goto_statements::require_struct_component_assignment( tmp_object_name, {}, "field_input2", - "java::SimpleWrapper", + "java::Wrapper", {}, entry_point_code); @@ -167,25 +167,25 @@ SCENARIO( require_goto_statements::require_entry_point_argument_assignment( "this", entry_point_code); - THEN("Object 'this' has field 'field_input1' of type SimpleWrapper") + THEN("Object 'this' has field 'field_input1' of type Wrapper") { const auto &field_input1_name = require_goto_statements::require_struct_component_assignment( tmp_object_name, {}, "field_input1", - "java::SimpleWrapper", + "java::Wrapper", {}, entry_point_code); - THEN("Object 'field_input1' has field 'field' of type SimpleWrapper") + THEN("Object 'field_input1' has field 'field' of type Wrapper") { const auto &field_name = require_goto_statements::require_struct_component_assignment( field_input1_name, {}, "field", - "java::SimpleWrapper", + "java::Wrapper", {}, entry_point_code); @@ -233,7 +233,7 @@ SCENARIO( require_goto_statements::require_struct_component_assignment( field_input_name, {}, - "key", + "first", "java::IWrapper", {}, entry_point_code); @@ -244,7 +244,7 @@ SCENARIO( require_goto_statements::require_struct_component_assignment( field_input_name, {}, - "value", + "second", "java::IWrapper", {}, entry_point_code); @@ -274,7 +274,7 @@ SCENARIO( require_goto_statements::require_entry_point_argument_assignment( "v", entry_point_code); - THEN("Object 'v' is of type SimpleWrapper") + THEN("Object 'v' is of type Wrapper") { const auto &tmp_object_declaration = require_goto_statements::require_declaration_of_name( @@ -284,7 +284,7 @@ SCENARIO( // and verify that it is what we expect. const auto &tmp_object_struct = to_struct_type(tmp_object_declaration.symbol().type()); - REQUIRE(tmp_object_struct.get_tag() == "SimpleWrapper"); + REQUIRE(tmp_object_struct.get_tag() == "Wrapper"); THEN("Object 'v' has field 'field' of type IWrapper") { @@ -323,7 +323,7 @@ SCENARIO( require_goto_statements::require_entry_point_argument_assignment( "v", entry_point_code); - THEN("Object 'v' is of type SimpleWrapper") + THEN("Object 'v' is of type Wrapper") { const auto &tmp_object_declaration = require_goto_statements::require_declaration_of_name( @@ -333,7 +333,7 @@ SCENARIO( // and verify that it is what we expect. const auto &tmp_object_struct = to_struct_type(tmp_object_declaration.symbol().type()); - REQUIRE(tmp_object_struct.get_tag() == "SimpleWrapper"); + REQUIRE(tmp_object_struct.get_tag() == "Wrapper"); THEN( "Object 'v' has field 'field' of type Object (upper bound of the " From f3cdd974e5be15621c64059ac0937840ef708544 Mon Sep 17 00:00:00 2001 From: svorenova Date: Wed, 21 Mar 2018 11:42:14 +0000 Subject: [PATCH 3/8] Add unit tests for mocked/unsupported generics --- .../goto_program_generics/GenericBases.java | 12 ++ .../GenericFieldMocked.class | Bin 0 -> 535 bytes .../GenericFieldUnsupported.class | Bin 0 -> 739 bytes .../goto_program_generics/GenericFields.java | 32 +++++ .../goto_program_generics/GenericHelper.java | 21 +++ .../InterfacePairWrapper.class | Bin 0 -> 295 bytes .../InterfacesImplementation.class | Bin 0 -> 1018 bytes .../SuperclassMocked.class | Bin 0 -> 465 bytes .../SuperclassUnsupported.class | Bin 0 -> 476 bytes .../UnsupportedWrapper1.class | Bin 0 -> 449 bytes .../UnsupportedWrapper2.class | Bin 0 -> 486 bytes .../generic_bases_test.cpp | 97 ++++++++++++++ .../generic_parameters_test.cpp | 122 ++++++++++++++++++ 13 files changed, 284 insertions(+) create mode 100644 unit/goto-programs/goto_program_generics/GenericFieldMocked.class create mode 100644 unit/goto-programs/goto_program_generics/GenericFieldUnsupported.class create mode 100644 unit/goto-programs/goto_program_generics/InterfacePairWrapper.class create mode 100644 unit/goto-programs/goto_program_generics/InterfacesImplementation.class create mode 100644 unit/goto-programs/goto_program_generics/SuperclassMocked.class create mode 100644 unit/goto-programs/goto_program_generics/SuperclassUnsupported.class create mode 100644 unit/goto-programs/goto_program_generics/UnsupportedWrapper1.class create mode 100644 unit/goto-programs/goto_program_generics/UnsupportedWrapper2.class diff --git a/unit/goto-programs/goto_program_generics/GenericBases.java b/unit/goto-programs/goto_program_generics/GenericBases.java index 6200a0edf43..87e5e922dc7 100644 --- a/unit/goto-programs/goto_program_generics/GenericBases.java +++ b/unit/goto-programs/goto_program_generics/GenericBases.java @@ -103,3 +103,15 @@ public void foo() { f.inner_three.foo(x); } } + +class SuperclassUnsupported extends UnsupportedWrapper1 { + public void foo() { + this.field = new SuperclassUnsupported(); + } +} + +class SuperclassMocked extends MockedWrapper { + public void foo() { + this.field.i = 5; + } +} diff --git a/unit/goto-programs/goto_program_generics/GenericFieldMocked.class b/unit/goto-programs/goto_program_generics/GenericFieldMocked.class new file mode 100644 index 0000000000000000000000000000000000000000..ccd2df812d56057a512881281caaf7b7170e4935 GIT binary patch literal 535 zcmZ8dO;5r=6r80krL|Z@{KOB`i*k^QH<618hNS8NgXg6zxL8^&;Qungn0PRr{ZYo( zA_yM#<;~lfd6W0`{r&;q3`Zt(tQ$yT!@wrCbZi??k=L=KW0!%o8Eoe|a34kMKIHwr z2+tXey6pITI0^+re(|^L)TX=&F_UHK%VC8QMR>=X9!;`N z;Bv3QLmA=Up*nn!1BRS)C43P|w_a&&wwM44Ft>^0?nA-8Q?z9WtaB?!ch6qd-yk|6Gd4B)u96 zbXuKGO&|(E)g+X_5@BXI(2KkF@MI{*Lx literal 0 HcmV?d00001 diff --git a/unit/goto-programs/goto_program_generics/GenericFieldUnsupported.class b/unit/goto-programs/goto_program_generics/GenericFieldUnsupported.class new file mode 100644 index 0000000000000000000000000000000000000000..692e93e4516034a0de077054bfb0075d19d1d5e1 GIT binary patch literal 739 zcmZ`%T~8B16g|`3?b3DSQv?*D0%}_l8jU=a@M3~#vcU(0#>eS)+D@~b-At$cFB1X@ zCWdEzl<`he+D+7lxifR_x#xb&Jp8`<1>hqN0|eMAp@bJDyu`MTS3Y(Ec-Rf#qHN7; zAA3Ib8CaKLJ-Sq*ah9dph)zrMEED=egQ0XGdy1Q}77XwI#W{(Z$_U-%u^2UnSt5o) z8E#~%8mAOrJdsM8QwFC}y<%`br5#dQilh?f<6&Fque_ZQvKpl^Pp-I@_C5t&)0ZQL zt?08*Ld*C}ilmdPlk}Z#nlc0z=~&0&OirZo?9tJHf9D~VupHtELLUbq-rz06=Ktzu zSZGcsVB_9}sGw?1jbS6NovVal+2*MyT=nW-+5-_AhP52waik1h*LGn$o)s{4Qaf&? zX~$F?3e!)C^t=*1*3ziXj|}CUV~*!2DAVHy^cm=VZR2F0(yf3+TCnpVWQ9)k2?OwI zw_raelvT1tf&qawvNo6qc!qV_sj69Uk5KD7u3e*W4d)*2Pk7&)TNH2LxBf=0*PD13 bTJvO!a7d(2!jeAkAeZ!bmUM#{1#JES3|yz& literal 0 HcmV?d00001 diff --git a/unit/goto-programs/goto_program_generics/GenericFields.java b/unit/goto-programs/goto_program_generics/GenericFields.java index 18441048806..3ba7c8e314d 100644 --- a/unit/goto-programs/goto_program_generics/GenericFields.java +++ b/unit/goto-programs/goto_program_generics/GenericFields.java @@ -80,3 +80,35 @@ public void foo(A v) { } } } + +// class that implements two generic interfaces +class InterfacesImplementation implements InterfaceWrapper, + InterfacePairWrapper { + public IWrapper method(IWrapper t) { + return t; + } + public IWrapper method(IWrapper t, IWrapper tt) { + if (t.i>0) + { + return t; + } + else + { + return tt; + } + } +} +class GenericFieldUnsupported { + public UnsupportedWrapper2 f; + public void foo() { + f.field.method(new IWrapper(0)); + f.field.method(new IWrapper(0), new IWrapper(2)); + } +} + +class GenericFieldMocked { + public MockedWrapper f; + public void foo() { + f.field.i = 0; + } +} diff --git a/unit/goto-programs/goto_program_generics/GenericHelper.java b/unit/goto-programs/goto_program_generics/GenericHelper.java index a871b5740cd..5cd559bdacd 100644 --- a/unit/goto-programs/goto_program_generics/GenericHelper.java +++ b/unit/goto-programs/goto_program_generics/GenericHelper.java @@ -23,3 +23,24 @@ class PairWrapper { interface InterfaceWrapper { public T method(T t); } + +// generic interface with two parameters +interface InterfacePairWrapper { + public K method(K k, V v); +} + +// generic class with unsupported signature - generic bound +class UnsupportedWrapper1> { + public T field; +} + +// generic class with unsupported signature - multiple bounds +class UnsupportedWrapper2 +{ + public T field; +} + +// generic mocked class, make sure the .class file is not available +class MockedWrapper { + public T field; +} diff --git a/unit/goto-programs/goto_program_generics/InterfacePairWrapper.class b/unit/goto-programs/goto_program_generics/InterfacePairWrapper.class new file mode 100644 index 0000000000000000000000000000000000000000..17c6e673c1c4053b99612922435faf3c500b3d6f GIT binary patch literal 295 zcmZvX%?`m(5QWcBt+o~-9zr*|u@DtYKOrH})cUGXm1>)t*27tN01qWDc4{#>bH4e> z%;R~x0~nxXz%pPH^a~fK>_8ayR%dY)ZX(jiUGL8v7G9M&RYWkiag>UpluWRD{?hXU z&rw1ckC&tBMDT}As%->oo0T%;X`HCdof)Sr<8aPN&a(eLme5_K19U#=y>q<339h&kDh4>4b*m`{`d literal 0 HcmV?d00001 diff --git a/unit/goto-programs/goto_program_generics/InterfacesImplementation.class b/unit/goto-programs/goto_program_generics/InterfacesImplementation.class new file mode 100644 index 0000000000000000000000000000000000000000..0e6ba2412e5eb4a853620f8c4c1fc352e53adcaa GIT binary patch literal 1018 zcmaJ<+iuf95It)rah*7AC~YX^7H%bJD)ImVq*RpdqY$$j6Pu>+uruq~bIzQd_0M15z5}?8MiCA!y0CG{L9K`aF6(f`!Bq#> z99(y>!BE(ip;S8zcD=F3kb4jf1jABShT`#L*cb6L-Vdm<+>Lx5?D1IY@1&Sh2Xf4? z-tB}+#P7H-#+~6P5JM3vu4ELpsliaFgJ{4|t#>;wVm=y)xZOy%3`{W;vxQm)nb!Z} zSc*vHp5p%dM|_mn*{F99`3K$#c(~ts(mxcwqE2%qhI=Of=W!=e-JaYJxthc@lQ;96 zbP~x`x6=#kwA0h4T*mW=ES6@{izcxzcBPsBLlKHt`nysDgYiv$DGx=IJlsH?Vd2kc zJ)FX_4yz1n|9TdN%JHdCX@*XWF|5o=8Nc*kl2!*b`kNeBSb$4ET%H#B0fR@o7G1o2$h|^dhj@DRB zG+t4*iCt=bhV>Eo=FyfGvyIrIIeJa*-;#H3L~B#{Oth4Uk_4(GZ{dvLGq-Y|`m7~= zZqb4E>TWiF!2W{Vam(4ux>I!{a5fRROMSJ`vJu!aBKiM`loN{<)`@1}9L}43;Wvv$ B%=7>N literal 0 HcmV?d00001 diff --git a/unit/goto-programs/goto_program_generics/SuperclassMocked.class b/unit/goto-programs/goto_program_generics/SuperclassMocked.class new file mode 100644 index 0000000000000000000000000000000000000000..c20879a9926f15ebd73dd580839ea3c2f56762a4 GIT binary patch literal 465 zcmZ8d%TB^T6g|_HmewK<-=c|2Wg#0^LRe^`A*s5+;Cd(n4%QZ@t^Z}BF>zsB`%%W* zg3raBb6@A2n|c3uc?EEQZ3iZnY!t9;Va0}yRSRnt))~yU3}w<`(0BLx490OZ6bxlg zhT=TE9SC*F2LW|zUgYzj&y~#TdDBR)Wt`1==~O5`;BkBw`8Q(NBE3-*G1xsh4tbI) zlBj#L;g#Z3T5o&ZdDiOCzSE0R<%<)Uxm8a^D3tV%cr4=m3BTtqEEHXAV3VQvMRZZe z7DMH~Jwxe_6+>YpMKH`x&BU4k568`m!9@58Su;t|#SZNoh5JE`_DS{$VkthX7&{#BvAj*qpI>hu08X&)z=UU^?LdQPQ`oi8VQ7qGB8xGDet0xtFwWCRFf@Ic zh^ulw73!K#W2$(58uEC;m8{;&qES4^oT2LnWhPV@^E|&v@-oX(RfuRvqO&w*umgFY z@S;?t)Av^Z1HcIe4s`TvY}@EFm=98<2}3`)%jQ*4W3FDoS&^e`mF@?<7UpXmO4`JWD;0}N*-UgLGNELA zEmGR`)i0D #include #include +#include // NOTE: To inspect these tests at any point, use expr2java. // A good way to verify the validity of a test is to iterate @@ -412,3 +413,99 @@ SCENARIO( } } } + +SCENARIO( + "Ignore generics for incomplete and non-generic bases", + "[core][goto_program_generics][generic_bases_test]") +{ + GIVEN( + "A class extending a generic class with unsupported class signature (thus" + " not marked as generic)") + { + const symbol_tablet &symbol_table = load_java_class( + "SuperclassUnsupported", + "./goto-programs/goto_program_generics", + "SuperclassUnsupported.foo"); + + THEN("The struct for UnsupportedWrapper1 is complete and non-generic") + { + const std::string superclass_name = "java::UnsupportedWrapper1"; + REQUIRE(symbol_table.has_symbol(superclass_name)); + + const symbolt &superclass_symbol = + symbol_table.lookup_ref(superclass_name); + require_type::require_java_non_generic_class(superclass_symbol.type); + } + + WHEN("The method input argument is created in the entry point function") + { + const std::vector &entry_point_code = + require_goto_statements::require_entry_point_statements(symbol_table); + + // For an explanation of this part, look at the comments for the similar + // parts of the previous tests. + const irep_idt &this_tmp_name = + require_goto_statements::require_entry_point_argument_assignment( + "this", entry_point_code); + + THEN("Object 'this' created has unspecialized inherited field") + { + require_goto_statements::require_struct_component_assignment( + this_tmp_name, + {"UnsupportedWrapper1"}, + "field", + "java::java.lang.Object", + {}, + entry_point_code); + } + } + } + + GIVEN( + "A class extending a generic class that is mocked (thus incomplete and not " + "marked as generic)") + { + const symbol_tablet &symbol_table = load_java_class( + "SuperclassMocked", + "./goto-programs/goto_program_generics", + "SuperclassMocked.foo"); + + THEN("The struct for MockedWrapper is incomplete and not-generic") + { + const std::string superclass_name = "java::MockedWrapper"; + REQUIRE(symbol_table.has_symbol(superclass_name)); + + const symbolt &superclass_symbol = + symbol_table.lookup_ref(superclass_name); + const java_class_typet &superclass_type = + to_java_class_type(to_class_type(superclass_symbol.type)); + REQUIRE( + to_class_type(superclass_symbol.type).get_bool(ID_incomplete_class)); + REQUIRE(!is_java_generic_class_type(superclass_type)); + REQUIRE(!is_java_implicitly_generic_class_type(superclass_type)); + } + + WHEN("The method input argument is created in the entry point function") + { + const std::vector &entry_point_code = + require_goto_statements::require_entry_point_statements(symbol_table); + + // For an explanation of this part, look at the comments for the similar + // parts of the previous tests. + const irep_idt &this_tmp_name = + require_goto_statements::require_entry_point_argument_assignment( + "this", entry_point_code); + + THEN("Object 'this' created has unspecialized inherited field") + { + require_goto_statements::require_struct_component_assignment( + this_tmp_name, + {"MockedWrapper"}, + "field", + "java::java.lang.Object", + {}, + entry_point_code); + } + } + } +} diff --git a/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp b/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp index d7ba2eea9ab..b01c9f6194d 100644 --- a/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp +++ b/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp @@ -9,6 +9,7 @@ #include #include #include +#include // NOTE: To inspect these tests at any point, use expr2java. // A good way to verify the validity of a test is to iterate @@ -486,3 +487,124 @@ SCENARIO( } } } + +SCENARIO( + "Ignore generic parameters in fields and methods with incomplete and " + "non-generic types", + "[core][goto_program_generics][generic_parameters_test]") +{ + GIVEN( + "A class with a generic field pointing to a class with unsupported " + "signature (thus not marked as generic)") + { + const symbol_tablet &symbol_table = load_java_class( + "GenericFieldUnsupported", + "./goto-programs/goto_program_generics", + "GenericFieldUnsupported.foo"); + + THEN("The struct for UnsupportedWrapper2 is complete and non-generic") + { + const std::string superclass_name = "java::UnsupportedWrapper2"; + REQUIRE(symbol_table.has_symbol(superclass_name)); + + const symbolt &superclass_symbol = + symbol_table.lookup_ref(superclass_name); + require_type::require_java_non_generic_class(superclass_symbol.type); + } + + WHEN("The method input argument is created in the entry point function") + { + // For an explanation of this part, look at the comments for the similar + // parts of the previous tests. + const std::vector &entry_point_code = + require_goto_statements::require_entry_point_statements(symbol_table); + + const irep_idt &tmp_object_name = + require_goto_statements::require_entry_point_argument_assignment( + "this", entry_point_code); + + THEN("Object 'this' has field 'f' of type UnsupportedWrapper2") + { + const auto &field_input_name = + require_goto_statements::require_struct_component_assignment( + tmp_object_name, + {}, + "f", + "java::UnsupportedWrapper2", + {}, + entry_point_code); + + THEN("Object 'f' has unspecialized field 'field'") + { + require_goto_statements::require_struct_component_assignment( + field_input_name, + {}, + "field", + "java::java.lang.Object", + {}, + entry_point_code); + } + } + } + } + + GIVEN( + "A class with a generic field pointing to a mocked class (thus " + "incomplete and not marked as generic)") + { + const symbol_tablet &symbol_table = load_java_class( + "GenericFieldMocked", + "./goto-programs/goto_program_generics", + "GenericFieldMocked.foo"); + + THEN("The struct for MockedWrapper is incomplete and not-generic") + { + const std::string superclass_name = "java::MockedWrapper"; + REQUIRE(symbol_table.has_symbol(superclass_name)); + + const symbolt &superclass_symbol = + symbol_table.lookup_ref(superclass_name); + const java_class_typet &superclass_type = + to_java_class_type(to_class_type(superclass_symbol.type)); + REQUIRE( + to_class_type(superclass_symbol.type).get_bool(ID_incomplete_class)); + REQUIRE(!is_java_generic_class_type(superclass_type)); + REQUIRE(!is_java_implicitly_generic_class_type(superclass_type)); + } + + WHEN("The method input argument is created in the entry point function") + { + // For an explanation of this part, look at the comments for the similar + // parts of the previous tests. + const std::vector &entry_point_code = + require_goto_statements::require_entry_point_statements(symbol_table); + + const irep_idt &tmp_object_name = + require_goto_statements::require_entry_point_argument_assignment( + "this", entry_point_code); + + THEN("Object 'this' has field 'f' of type MockedWrapper") + { + const auto &field_input_name = + require_goto_statements::require_struct_component_assignment( + tmp_object_name, + {}, + "f", + "java::MockedWrapper", + {}, + entry_point_code); + + THEN("Object 'f' has unspecialized field 'field'") + { + require_goto_statements::require_struct_component_assignment( + field_input_name, + {}, + "field", + "java::java.lang.Object", + {}, + entry_point_code); + } + } + } + } +} From 3a45ee9e6344fda66927c30006b8038d8c85b27d Mon Sep 17 00:00:00 2001 From: svorenova Date: Wed, 21 Mar 2018 12:25:37 +0000 Subject: [PATCH 4/8] Improving warnings for unsupported signatures for generics --- .../java_bytecode_convert_class.cpp | 26 +++++++++++-------- .../java_bytecode_convert_method.cpp | 4 +-- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 6c84b21f532..317c4f3c361 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -202,10 +202,12 @@ void java_bytecode_convert_classt::convert(const classt &c) } class_type=generic_class_type; } - catch(unsupported_java_class_signature_exceptiont) + catch(unsupported_java_class_signature_exceptiont &e) { - warning() << "we currently don't support parsing for example double " - "bounded, recursive and wild card generics" << eom; + warning() << "Class: " << c.name + << "\n could not parse signature: " << c.signature.value() + << "\n " << e.what() << "\n ignoring that the class is generic" + << eom; } } @@ -253,11 +255,12 @@ void java_bytecode_convert_classt::convert(const classt &c) base, superclass_ref.value(), qualified_classname); class_type.add_base(generic_base); } - catch(unsupported_java_class_signature_exceptiont) + catch(unsupported_java_class_signature_exceptiont &e) { - debug() << "unsupported generic superclass signature " - << id2string(*superclass_ref) - << " falling back on using the descriptor" << eom; + warning() << "Superclass: " << c.extends << " of class: " << c.name + << "\n could not parse signature: " << superclass_ref.value() + << "\n " << e.what() + << "\n ignoring that the superclass is generic" << eom; class_type.add_base(base); } } @@ -292,11 +295,12 @@ void java_bytecode_convert_classt::convert(const classt &c) base, interface_ref.value(), qualified_classname); class_type.add_base(generic_base); } - catch(unsupported_java_class_signature_exceptiont) + catch(unsupported_java_class_signature_exceptiont &e) { - debug() << "unsupported generic interface signature " - << id2string(*interface_ref) - << " falling back on using the descriptor" << eom; + warning() << "Interface: " << interface << " of class: " << c.name + << "\n could not parse signature: " << interface_ref.value() + << "\n " << e.what() + << "\n ignoring that the interface is generic" << eom; class_type.add_base(base); } } diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 366674e85dc..7d19ac2e7d7 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -286,7 +286,7 @@ code_typet member_type_lazy( } else { - message.warning() << "method: " << class_name << "." << method_name + message.warning() << "Method: " << class_name << "." << method_name << "\n signature: " << signature.value() << "\n descriptor: " << descriptor << "\n different number of parameters, reverting to " "descriptor" << message.eom; @@ -294,7 +294,7 @@ code_typet member_type_lazy( } catch(unsupported_java_class_signature_exceptiont &e) { - message.warning() << "method: " << class_name << "." << method_name + message.warning() << "Method: " << class_name << "." << method_name << "\n could not parse signature: " << signature.value() << "\n " << e.what() << "\n" << " reverting to descriptor: " << descriptor << message.eom; From 11e9a77864ce50fc4836be70680c753534e296ad Mon Sep 17 00:00:00 2001 From: svorenova Date: Thu, 22 Mar 2018 17:04:58 +0000 Subject: [PATCH 5/8] Ignore generic arguments for mocked and unsupported generic classes cont. --- ...eric_parameter_specialization_map_keys.cpp | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/java_bytecode/generic_parameter_specialization_map_keys.cpp b/src/java_bytecode/generic_parameter_specialization_map_keys.cpp index e36c5853e8e..18cc04a0918 100644 --- a/src/java_bytecode/generic_parameter_specialization_map_keys.cpp +++ b/src/java_bytecode/generic_parameter_specialization_map_keys.cpp @@ -99,10 +99,14 @@ const void generic_parameter_specialization_map_keyst::insert_pairs_for_pointer( pointer_type.subtype().get(ID_identifier) == pointer_subtype_struct.get(ID_name)); - // If the pointer points to an incomplete class, don't treat the generics - // TODO TG-1996 should treat generic incomplete (mocked) classes - // Also do not treat generics is the class is not marked generic or - // implicitly generic (this may be due to unsupported class signature) + // If the pointer points to: + // - an incomplete class or + // - a class that is neither generic nor implicitly generic (this + // may be due to unsupported class signature) + // then ignore the generic types in the pointer and do not add any pairs. + // TODO TG-1996 should decide how mocking and generics should work + // together. Currently an incomplete class is never marked as generic. If + // this changes in TG-1996 then the condition below should be updated. if( !pointer_subtype_struct.get_bool(ID_incomplete_class) && (is_java_generic_class_type(pointer_subtype_struct) || @@ -137,10 +141,14 @@ const void generic_parameter_specialization_map_keyst::insert_pairs_for_symbol( const symbol_typet &symbol_type, const typet &symbol_struct) { - // If the class is an incomplete class, don't treat the generics - // TODO TG-1996 should treat generic incomplete (mocked) classes - // Also do not treat generics is the class is not marked generic or - // implicitly generic (this may be due to unsupported class signature) + // If the struct is: + // - an incomplete class or + // - a class that is neither generic nor implicitly generic (this + // may be due to unsupported class signature) + // then ignore the generic types in the symbol_type and do not add any pairs. + // TODO TG-1996 should decide how mocking and generics should work + // together. Currently an incomplete class is never marked as generic. If + // this changes in TG-1996 then the condition below should be updated. if( is_java_generic_symbol_type(symbol_type) && !symbol_struct.get_bool(ID_incomplete_class) && From 067eeff9098858a6c498bdb8c87d5c9233a73353 Mon Sep 17 00:00:00 2001 From: svorenova Date: Fri, 23 Mar 2018 11:06:54 +0000 Subject: [PATCH 6/8] Refactoring and adding utility functions in require_type --- .../parse_bounded_generic_inner_classes.cpp | 10 +- .../parse_derived_generic_class.cpp | 52 ++++--- .../parse_generic_array_class.cpp | 2 +- .../parse_generic_class.cpp | 4 +- ...neric_class_with_generic_inner_classes.cpp | 2 +- ...parse_generic_class_with_inner_classes.cpp | 16 +-- .../parse_generic_fields.cpp | 2 +- .../parse_nested_generics.cpp | 2 +- .../parse_signature_descriptor_mismatch.cpp | 6 +- unit/testing-utils/require_type.cpp | 130 +++++++++++++++--- unit/testing-utils/require_type.h | 22 +++ 11 files changed, 185 insertions(+), 63 deletions(-) diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_bounded_generic_inner_classes.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_bounded_generic_inner_classes.cpp index 16036dbe05f..7c8eb84bc38 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_bounded_generic_inner_classes.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_bounded_generic_inner_classes.cpp @@ -23,7 +23,7 @@ SCENARIO( const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); const java_class_typet &java_class_type = - require_type::require_java_non_generic_class(class_symbol.type); + require_type::require_complete_java_non_generic_class(class_symbol.type); WHEN("Parsing an inner class with type variable") { @@ -33,7 +33,7 @@ SCENARIO( { const symbolt &class_symbol = new_symbol_table.lookup_ref(inner_name); const java_generic_class_typet &java_generic_class_type = - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {inner_name + "::E"}); THEN("The fields are of correct types") @@ -56,7 +56,7 @@ SCENARIO( const symbolt &class_symbol = new_symbol_table.lookup_ref(boundedinner_name); const java_generic_class_typet &java_generic_class_type = - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {boundedinner_name + "::NUM"}); // TODO extend when bounds are parsed correctly - TG-1286 @@ -94,7 +94,7 @@ SCENARIO( new_symbol_table.lookup_ref(doubleboundedinner_name); // TODO the symbol should be generic - TG-1349 // const java_generic_class_typet &java_generic_class_type = - // require_type::require_java_generic_class( + // require_type::require_complete_java_generic_class( // class_symbol.type, {doubleboundedinner_name + "::T"}); // TODO extend when bounds are parsed correctly - TG-1286 @@ -121,7 +121,7 @@ SCENARIO( const symbolt &class_symbol = new_symbol_table.lookup_ref(twoelementinner_name); const java_generic_class_typet &java_generic_class_type = - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {twoelementinner_name + "::K", twoelementinner_name + "::V"}); diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_derived_generic_class.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_derived_generic_class.cpp index 000c630415f..471c896281d 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_derived_generic_class.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_derived_generic_class.cpp @@ -24,7 +24,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_non_generic_class(derived_symbol.type); + require_type::require_complete_java_non_generic_class( + derived_symbol.type); THEN("The base for superclass has the correct generic type information") { @@ -46,7 +47,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_non_generic_class(derived_symbol.type); + require_type::require_complete_java_non_generic_class( + derived_symbol.type); THEN("The base for superclass has the correct generic type information") { @@ -69,7 +71,7 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_generic_class(derived_symbol.type); + require_type::require_complete_java_generic_class(derived_symbol.type); THEN("The base for superclasss has the correct generic type information") { @@ -91,7 +93,7 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_generic_class(derived_symbol.type); + require_type::require_complete_java_generic_class(derived_symbol.type); THEN("The base for superclass has the correct generic type information") { @@ -113,7 +115,7 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_generic_class(derived_symbol.type); + require_type::require_complete_java_generic_class(derived_symbol.type); THEN("The base for superclass has the correct generic type information") { @@ -136,7 +138,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_non_generic_class(derived_symbol.type); + require_type::require_complete_java_non_generic_class( + derived_symbol.type); THEN("The base for superclass has the correct generic type information") { @@ -159,7 +162,7 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_generic_class(derived_symbol.type); + require_type::require_complete_java_generic_class(derived_symbol.type); THEN("The base for superclass has the correct generic type information") { @@ -183,7 +186,7 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_implicitly_generic_class( + require_type::require_complete_java_implicitly_generic_class( derived_symbol.type, {"java::ContainsInnerClassGeneric::T"}); THEN("The base for superclass has the correct generic type information") @@ -206,7 +209,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_non_generic_class(derived_symbol.type); + require_type::require_complete_java_non_generic_class( + derived_symbol.type); THEN("The base for superclass has the correct generic type information") { @@ -229,7 +233,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_non_generic_class(derived_symbol.type); + require_type::require_complete_java_non_generic_class( + derived_symbol.type); THEN("The bases have the correct generic type information") { @@ -261,7 +266,7 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_generic_class(derived_symbol.type); + require_type::require_complete_java_generic_class(derived_symbol.type); THEN("The bases have the correct generic type information") { @@ -294,7 +299,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_non_generic_class(derived_symbol.type); + require_type::require_complete_java_non_generic_class( + derived_symbol.type); THEN("The bases have the correct generic type information") { @@ -332,7 +338,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_non_generic_class(derived_symbol.type); + require_type::require_complete_java_non_generic_class( + derived_symbol.type); THEN("The bases have the correct generic type information") { @@ -374,7 +381,7 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_generic_class(derived_symbol.type); + require_type::require_complete_java_generic_class(derived_symbol.type); THEN("The bases have the correct generic type information") { @@ -418,7 +425,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_non_generic_class(derived_symbol.type); + require_type::require_complete_java_non_generic_class( + derived_symbol.type); THEN("The bases have the correct generic type information") { @@ -455,7 +463,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_non_generic_class(derived_symbol.type); + require_type::require_complete_java_non_generic_class( + derived_symbol.type); THEN("The bases have the correct generic type information") { @@ -499,7 +508,7 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_generic_class(derived_symbol.type); + require_type::require_complete_java_generic_class(derived_symbol.type); THEN("The bases have the correct generic type information") { @@ -533,7 +542,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_implicitly_generic_class(derived_symbol.type); + require_type::require_complete_java_implicitly_generic_class( + derived_symbol.type); THEN("The base for superclass is implicitly generic") { @@ -553,7 +563,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_implicitly_generic_class(derived_symbol.type); + require_type::require_complete_java_implicitly_generic_class( + derived_symbol.type); THEN("The base for superclass is generic *and* implicitly generic") { @@ -575,7 +586,8 @@ SCENARIO( const symbolt &derived_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &derived_class_type = - require_type::require_java_implicitly_generic_class(derived_symbol.type); + require_type::require_complete_java_implicitly_generic_class( + derived_symbol.type); THEN("The base for superclass is generic *and* implicitly generic") { diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_array_class.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_array_class.cpp index 126454ad71d..2290733637e 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_array_class.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_array_class.cpp @@ -22,7 +22,7 @@ SCENARIO( const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); const java_generic_class_typet &java_generic_class = - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {class_prefix + "::T"}); THEN("There should be field t") diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class.cpp index 5717ff29f3a..cc5e540b7e0 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class.cpp @@ -27,7 +27,7 @@ SCENARIO( const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); const java_generic_class_typet &java_generic_class = - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {class_prefix + "::T"}); const struct_typet class_struct = to_struct_type(class_symbol.type); @@ -79,7 +79,7 @@ SCENARIO( const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); const java_generic_class_typet &java_generic_class = - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {class_prefix + "::T", class_prefix + "::U"}); const struct_typet class_struct = to_struct_type(class_symbol.type); diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_generic_inner_classes.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_generic_inner_classes.cpp index 5c70107e5e7..666952b242a 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_generic_inner_classes.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_generic_inner_classes.cpp @@ -26,7 +26,7 @@ SCENARIO( REQUIRE(new_symbol_table.has_symbol(class_prefix)); const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); const java_generic_class_typet &java_generic_class = - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {class_prefix + "::T"}); THEN( diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_inner_classes.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_inner_classes.cpp index 6196edfe33c..b90ad2b3c68 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_inner_classes.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_class_with_inner_classes.cpp @@ -26,7 +26,7 @@ SCENARIO( const symbolt &class_symbol = new_symbol_table.lookup_ref(outer_class_prefix); const java_generic_class_typet &generic_class = - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {outer_class_prefix + "::T"}); THEN("There is a field f1 of generic type with correct arguments") { @@ -68,7 +68,7 @@ SCENARIO( THEN("It has correct implicit generic types") { const java_implicitly_generic_class_typet &java_class = - require_type::require_java_implicitly_generic_class( + require_type::require_complete_java_implicitly_generic_class( class_symbol.type, {outer_class_prefix + "::T"}); THEN( @@ -105,7 +105,7 @@ SCENARIO( THEN("It has correct implicit generic types") { const java_implicitly_generic_class_typet &java_class = - require_type::require_java_implicitly_generic_class( + require_type::require_complete_java_implicitly_generic_class( class_symbol.type, {outer_class_prefix + "::T"}); THEN( @@ -149,10 +149,10 @@ SCENARIO( THEN("It has correct generic types and implicit generic types") { - require_type::require_java_implicitly_generic_class( + require_type::require_complete_java_implicitly_generic_class( class_symbol.type, {outer_class_prefix + "::T"}); const java_generic_class_typet &generic_class = - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {generic_inner_class_prefix + "::U"}); THEN( @@ -194,10 +194,10 @@ SCENARIO( THEN("It has correct generic types and implicit generic types") { - require_type::require_java_implicitly_generic_class( + require_type::require_complete_java_implicitly_generic_class( class_symbol.type, {outer_class_prefix + "::T", outer_class_prefix + "$GenericInner::U"}); - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {generic_inner_inner_class_prefix + "::V"}); } } @@ -212,7 +212,7 @@ SCENARIO( THEN("It has correct generic types and no implicit generic types") { REQUIRE(!is_java_implicitly_generic_class_type(class_symbol.type)); - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {static_inner_class_prefix + "::U"}); } } diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_fields.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_fields.cpp index 149f46bcee2..d0c7916ad0b 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_fields.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_generic_fields.cpp @@ -27,7 +27,7 @@ SCENARIO( const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); const java_generic_class_typet &java_generic_class_type = - require_type::require_java_generic_class( + require_type::require_complete_java_generic_class( class_symbol.type, {class_prefix + "::T", class_prefix + "::S"}); const struct_typet class_struct = to_struct_type(class_symbol.type); diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_nested_generics.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_nested_generics.cpp index 76eac25d9c7..26201973561 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_nested_generics.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_nested_generics.cpp @@ -24,7 +24,7 @@ SCENARIO( const symbolt &class_symbol = new_symbol_table.lookup_ref(class_prefix); const class_typet &class_type = - require_type::require_java_non_generic_class(class_symbol.type); + require_type::require_complete_java_non_generic_class(class_symbol.type); THEN("The field component should be a pointer to java::Generic") { diff --git a/unit/java_bytecode/java_bytecode_parse_generics/parse_signature_descriptor_mismatch.cpp b/unit/java_bytecode/java_bytecode_parse_generics/parse_signature_descriptor_mismatch.cpp index 38cbf85a65e..ae5d70318f5 100644 --- a/unit/java_bytecode/java_bytecode_parse_generics/parse_signature_descriptor_mismatch.cpp +++ b/unit/java_bytecode/java_bytecode_parse_generics/parse_signature_descriptor_mismatch.cpp @@ -28,7 +28,8 @@ SCENARIO( const symbolt &inner_symbol = new_symbol_table.lookup_ref(inner_prefix); const class_typet &inner_class_type = - require_type::require_java_implicitly_generic_class(inner_symbol.type); + require_type::require_complete_java_implicitly_generic_class( + inner_symbol.type); } THEN( @@ -63,7 +64,8 @@ SCENARIO( const symbolt &inner_enum_symbol = new_symbol_table.lookup_ref(inner_enum_prefix); - require_type::require_java_non_generic_class(inner_enum_symbol.type); + require_type::require_complete_java_non_generic_class( + inner_enum_symbol.type); } THEN( diff --git a/unit/testing-utils/require_type.cpp b/unit/testing-utils/require_type.cpp index 4bcb94aaecb..0ea4bf2e1b2 100644 --- a/unit/testing-utils/require_type.cpp +++ b/unit/testing-utils/require_type.cpp @@ -214,7 +214,7 @@ const typet &require_type::require_java_non_generic_type( /// Checks that the given type is a complete class. /// \param class_type type of the class /// \return class_type of the class -class_typet require_complete_class(const typet &class_type) +class_typet require_type::require_complete_class(const typet &class_type) { REQUIRE(class_type.id() == ID_struct); @@ -225,23 +225,40 @@ class_typet require_complete_class(const typet &class_type) return class_class_type; } -/// Verify that a class is a complete, valid java generic class. +/// Checks that the given type is an incomplete class. +/// \param class_type type of the class +/// \return class_type of the class +class_typet require_type::require_incomplete_class(const typet &class_type) +{ + REQUIRE(class_type.id() == ID_struct); + + const class_typet &class_class_type = to_class_type(class_type); + REQUIRE(class_class_type.is_class()); + REQUIRE(class_class_type.get_bool(ID_incomplete_class)); + + return class_class_type; +} + +/// Verify that a class is a valid java generic class. /// \param class_type: the class /// \return: A reference to the java generic class type. java_generic_class_typet require_type::require_java_generic_class(const typet &class_type) { - const class_typet &class_class_type = require_complete_class(class_type); - java_class_typet java_class_type = to_java_class_type(class_class_type); + REQUIRE(class_type.id() == ID_struct); + + const class_typet &class_class_type = to_class_type(class_type); + const java_class_typet &java_class_type = + to_java_class_type(class_class_type); REQUIRE(is_java_generic_class_type(java_class_type)); - java_generic_class_typet java_generic_class_type = + const java_generic_class_typet &java_generic_class_type = to_java_generic_class_type(java_class_type); return java_generic_class_type; } -/// Verify that a class is a complete, valid java generic class with the +/// Verify that a class is a valid java generic class with the /// specified list of variables. /// \param class_type: the class /// \param type_variables: vector of type variables @@ -251,7 +268,7 @@ java_generic_class_typet require_type::require_java_generic_class( const std::initializer_list &type_variables) { const java_generic_class_typet java_generic_class_type = - require_type::require_java_generic_class(class_type); + require_java_generic_class(class_type); const java_generic_class_typet::generic_typest &generic_type_vars = java_generic_class_type.generic_types(); @@ -261,8 +278,9 @@ java_generic_class_typet require_type::require_java_generic_class( type_variables.begin(), type_variables.end(), generic_type_vars.begin(), - [](const irep_idt &type_var_name, const java_generic_parametert ¶m) - { + []( + const irep_idt &type_var_name, + const java_generic_parametert ¶m) { //NOLINT REQUIRE(is_java_generic_parameter(param)); return param.type_variable().get_identifier() == type_var_name; })); @@ -270,23 +288,50 @@ java_generic_class_typet require_type::require_java_generic_class( return java_generic_class_type; } -/// Verify that a class is a complete, valid java implicitly generic class. +/// Verify that a class is a complete, valid java generic class. +/// \param class_type: the class +/// \return: A reference to the java generic class type. +java_generic_class_typet +require_type::require_complete_java_generic_class(const typet &class_type) +{ + require_complete_class(class_type); + return require_java_generic_class(class_type); +} + +/// Verify that a class is a complete, valid java generic class with the +/// specified list of variables. +/// \param class_type: the class +/// \param type_variables: vector of type variables +/// \return: A reference to the java generic class type. +java_generic_class_typet require_type::require_complete_java_generic_class( + const typet &class_type, + const std::initializer_list &type_variables) +{ + require_complete_java_generic_class(class_type); + return require_java_generic_class(class_type, type_variables); +} + +/// Verify that a class is a valid java implicitly generic class. /// \param class_type: the class /// \return: A reference to the java generic class type. java_implicitly_generic_class_typet require_type::require_java_implicitly_generic_class(const typet &class_type) { - const class_typet &class_class_type = require_complete_class(class_type); - java_class_typet java_class_type = to_java_class_type(class_class_type); + REQUIRE(class_type.id() == ID_struct); + + const class_typet &class_class_type = to_class_type(class_type); + const java_class_typet &java_class_type = + to_java_class_type(class_class_type); REQUIRE(is_java_implicitly_generic_class_type(java_class_type)); - java_implicitly_generic_class_typet java_implicitly_generic_class_type = - to_java_implicitly_generic_class_type(java_class_type); + const java_implicitly_generic_class_typet + &java_implicitly_generic_class_type = + to_java_implicitly_generic_class_type(java_class_type); return java_implicitly_generic_class_type; } -/// Verify that a class is a complete, valid java generic class with the +/// Verify that a class is a valid java generic class with the /// specified list of variables. /// \param class_type: the class /// \param type_variables: vector of type variables @@ -296,8 +341,9 @@ require_type::require_java_implicitly_generic_class( const typet &class_type, const std::initializer_list &implicit_type_variables) { - const java_implicitly_generic_class_typet java_implicitly_generic_class_type = - require_type::require_java_implicitly_generic_class(class_type); + const java_implicitly_generic_class_typet + &java_implicitly_generic_class_type = + require_java_implicitly_generic_class(class_type); const java_implicitly_generic_class_typet::implicit_generic_typest &implicit_generic_type_vars = @@ -308,8 +354,9 @@ require_type::require_java_implicitly_generic_class( implicit_type_variables.begin(), implicit_type_variables.end(), implicit_generic_type_vars.begin(), - [](const irep_idt &type_var_name, const java_generic_parametert ¶m) - { + []( + const irep_idt &type_var_name, + const java_generic_parametert ¶m) { //NOLINT REQUIRE(is_java_generic_parameter(param)); return param.type_variable().get_identifier() == type_var_name; })); @@ -317,14 +364,43 @@ require_type::require_java_implicitly_generic_class( return java_implicitly_generic_class_type; } -/// Verify that a class is a complete, valid nongeneric java class +/// Verify that a class is a complete, valid java implicitly generic class. +/// \param class_type: the class +/// \return: A reference to the java generic class type. +java_implicitly_generic_class_typet +require_type::require_complete_java_implicitly_generic_class( + const typet &class_type) +{ + require_complete_class(class_type); + return require_java_implicitly_generic_class(class_type); +} + +/// Verify that a class is a complete, valid java generic class with the +/// specified list of variables. +/// \param class_type: the class +/// \param type_variables: vector of type variables +/// \return: A reference to the java generic class type. +java_implicitly_generic_class_typet +require_type::require_complete_java_implicitly_generic_class( + const typet &class_type, + const std::initializer_list &implicit_type_variables) +{ + require_complete_class(class_type); + return require_java_implicitly_generic_class( + class_type, implicit_type_variables); +} + +/// Verify that a class is a valid nongeneric java class /// \param class_type: the class /// \return: A reference to the java generic class type. java_class_typet require_type::require_java_non_generic_class(const typet &class_type) { - const class_typet &class_class_type = require_complete_class(class_type); - java_class_typet java_class_type = to_java_class_type(class_class_type); + REQUIRE(class_type.id() == ID_struct); + + const class_typet &class_class_type = to_class_type(class_type); + const java_class_typet &java_class_type = + to_java_class_type(class_class_type); REQUIRE(!is_java_generic_class_type(java_class_type)); REQUIRE(!is_java_implicitly_generic_class_type(java_class_type)); @@ -332,6 +408,16 @@ require_type::require_java_non_generic_class(const typet &class_type) return java_class_type; } +/// Verify that a class is a complete, valid nongeneric java class +/// \param class_type: the class +/// \return: A reference to the java generic class type. +java_class_typet +require_type::require_complete_java_non_generic_class(const typet &class_type) +{ + require_complete_class(class_type); + return require_java_non_generic_class(class_type); +} + /// Verify a given type is a symbol type, optionally with a specific identifier /// \param type: The type to check /// \param identifier: The identifier the symbol type should have diff --git a/unit/testing-utils/require_type.h b/unit/testing-utils/require_type.h index ccf5db53315..66c76940a7a 100644 --- a/unit/testing-utils/require_type.h +++ b/unit/testing-utils/require_type.h @@ -70,9 +70,20 @@ const typet &require_java_non_generic_type( const typet &type, const optionalt &expect_subtype); +class_typet require_complete_class(const typet &class_type); + +class_typet require_incomplete_class(const typet &class_type); + java_generic_class_typet require_java_generic_class(const typet &class_type); java_generic_class_typet require_java_generic_class( + const typet &class_type, + const std::initializer_list &type_variables); + +java_generic_class_typet +require_complete_java_generic_class(const typet &class_type); + +java_generic_class_typet require_complete_java_generic_class( const typet &class_type, const std::initializer_list &type_parameters); @@ -83,8 +94,19 @@ java_implicitly_generic_class_typet require_java_implicitly_generic_class( const typet &class_type, const std::initializer_list &implicit_type_variables); +java_implicitly_generic_class_typet +require_complete_java_implicitly_generic_class(const typet &class_type); + +java_implicitly_generic_class_typet +require_complete_java_implicitly_generic_class( + const typet &class_type, + const std::initializer_list &implicit_type_variables); + java_class_typet require_java_non_generic_class(const typet &class_type); +java_class_typet +require_complete_java_non_generic_class(const typet &class_type); + java_generic_symbol_typet require_java_generic_symbol_type( const typet &type, const std::string &identifier); From c63c05b811c97c95610378288a9c64bafbf92cc9 Mon Sep 17 00:00:00 2001 From: svorenova Date: Fri, 23 Mar 2018 11:07:12 +0000 Subject: [PATCH 7/8] Add unit tests for mocked/unsupported generics cont. --- .../goto_program_generics/GenericBases.java | 4 +- ...dMocked.class => GenericFieldOpaque.class} | Bin 535 -> 535 bytes .../goto_program_generics/GenericFields.java | 4 +- .../goto_program_generics/GenericHelper.java | 4 +- .../SuperclassInnerUninstTest.class | Bin 1103 -> 1116 bytes ...assMocked.class => SuperclassOpaque.class} | Bin 465 -> 465 bytes .../generic_bases_test.cpp | 42 ++++++++------- .../generic_parameters_test.cpp | 49 ++++++++++-------- 8 files changed, 55 insertions(+), 48 deletions(-) rename unit/goto-programs/goto_program_generics/{GenericFieldMocked.class => GenericFieldOpaque.class} (52%) rename unit/goto-programs/goto_program_generics/{SuperclassMocked.class => SuperclassOpaque.class} (64%) diff --git a/unit/goto-programs/goto_program_generics/GenericBases.java b/unit/goto-programs/goto_program_generics/GenericBases.java index 87e5e922dc7..fc4da5293dd 100644 --- a/unit/goto-programs/goto_program_generics/GenericBases.java +++ b/unit/goto-programs/goto_program_generics/GenericBases.java @@ -97,7 +97,7 @@ class SuperclassInnerUninstTest { SuperclassInnerUninst f; public void foo() { - IWrapper x = new IWrapper(); + IWrapper x = new IWrapper(0); f.inner.foo(x); f.inner_gen.foo(x,true); f.inner_three.foo(x); @@ -110,7 +110,7 @@ public void foo() { } } -class SuperclassMocked extends MockedWrapper { +class SuperclassOpaque extends OpaqueWrapper { public void foo() { this.field.i = 5; } diff --git a/unit/goto-programs/goto_program_generics/GenericFieldMocked.class b/unit/goto-programs/goto_program_generics/GenericFieldOpaque.class similarity index 52% rename from unit/goto-programs/goto_program_generics/GenericFieldMocked.class rename to unit/goto-programs/goto_program_generics/GenericFieldOpaque.class index ccd2df812d56057a512881281caaf7b7170e4935..af3ed9cbcabfb895e94ef1077de726f68a2303b3 100644 GIT binary patch delta 78 zcmbQvGM#0DzKVZAVqs}&cu`_OL28jTBLin}W_n&?Noi3kBZIULM0R3u1{;)hFbc|= NtjH(^W7;y_0ss`R8u0)C delta 78 zcmbQvGM#0DzKU;ta&~G;cu`_OL28jTBLin}W_n&?Noi3kBZIULM0R3u1{;)hFbc|= NtjH(^W7;y_0ssaB8hHQ! diff --git a/unit/goto-programs/goto_program_generics/GenericFields.java b/unit/goto-programs/goto_program_generics/GenericFields.java index 3ba7c8e314d..b83152c95b4 100644 --- a/unit/goto-programs/goto_program_generics/GenericFields.java +++ b/unit/goto-programs/goto_program_generics/GenericFields.java @@ -106,8 +106,8 @@ public void foo() { } } -class GenericFieldMocked { - public MockedWrapper f; +class GenericFieldOpaque { + public OpaqueWrapper f; public void foo() { f.field.i = 0; } diff --git a/unit/goto-programs/goto_program_generics/GenericHelper.java b/unit/goto-programs/goto_program_generics/GenericHelper.java index 5cd559bdacd..fb7c9e73e0d 100644 --- a/unit/goto-programs/goto_program_generics/GenericHelper.java +++ b/unit/goto-programs/goto_program_generics/GenericHelper.java @@ -40,7 +40,7 @@ class UnsupportedWrapper2 public T field; } -// generic mocked class, make sure the .class file is not available -class MockedWrapper { +// generic opaque class, make sure the .class file is not available +class OpaqueWrapper { public T field; } diff --git a/unit/goto-programs/goto_program_generics/SuperclassInnerUninstTest.class b/unit/goto-programs/goto_program_generics/SuperclassInnerUninstTest.class index 18e5b60fdcd0c01000e2e8ecd0521977d5588149..bdf06a3383f22c6976087eb669b4217ae56ee625 100644 GIT binary patch delta 263 zcmXAj%Su8~6o$XOPq96loq?2^rDb07c+Ju-TG?eJ)UcqbkTs2-M9vG?GdN4Ad6Qls z=uM(^X!QM;#p3^peaCJ-f8XAL4p){Xa)wQdX3NKs_t~akDN>45*|I~$5>Sn7%~Gdi zXc(FbHCCjq!&kjJ8U1tb7k4ZDsu9Yfc##)0FIV?)o;=frRtg=dZd7lzC5S+y4z zD#PGzHdP57f5DR_(3+#~z3{{9-}*eT!k7Y&GzS0qQlr#fCvcC7>Anx^H7TTRR2(YD;t(R3{jJZgGj*tZNAYMvEdcp5B}xB5_r zPHav@T0nD+GY&S9-kZymBYg6_(_ltIriuR@lBC4BQZLO3O43vD4rkm5)AFkzg|9_d Kg!jU_@Co*v2p%H< diff --git a/unit/goto-programs/goto_program_generics/SuperclassMocked.class b/unit/goto-programs/goto_program_generics/SuperclassOpaque.class similarity index 64% rename from unit/goto-programs/goto_program_generics/SuperclassMocked.class rename to unit/goto-programs/goto_program_generics/SuperclassOpaque.class index c20879a9926f15ebd73dd580839ea3c2f56762a4..3b384284877854a5f623ec576f99c34fefdfbc71 100644 GIT binary patch delta 65 zcmcb}e35xViL!q|Vqs~jH6sIaT7Etw17~n%dR}5lX;CU8gR~Dsa^mzDeh7<^ffvG< I%*1#e0JpFeDF6Tf delta 65 zcmcb}e35xViL!5ga&~HpH6sIaT7Etw17~n%dR}5lX;CU8gR~Dsa^mzDeh7<^ffvG< I%*1#e0Inbu$p8QV diff --git a/unit/goto-programs/goto_program_generics/generic_bases_test.cpp b/unit/goto-programs/goto_program_generics/generic_bases_test.cpp index 33c780e6aa0..e29fe0d9223 100644 --- a/unit/goto-programs/goto_program_generics/generic_bases_test.cpp +++ b/unit/goto-programs/goto_program_generics/generic_bases_test.cpp @@ -10,6 +10,7 @@ #include #include #include +#include // NOTE: To inspect these tests at any point, use expr2java. // A good way to verify the validity of a test is to iterate @@ -430,11 +431,11 @@ SCENARIO( THEN("The struct for UnsupportedWrapper1 is complete and non-generic") { const std::string superclass_name = "java::UnsupportedWrapper1"; - REQUIRE(symbol_table.has_symbol(superclass_name)); - const symbolt &superclass_symbol = - symbol_table.lookup_ref(superclass_name); - require_type::require_java_non_generic_class(superclass_symbol.type); + require_symbol::require_symbol_exists(symbol_table, superclass_name); + + require_type::require_complete_java_non_generic_class( + superclass_symbol.type); } WHEN("The method input argument is created in the entry point function") @@ -442,14 +443,20 @@ SCENARIO( const std::vector &entry_point_code = require_goto_statements::require_entry_point_statements(symbol_table); - // For an explanation of this part, look at the comments for the similar - // parts of the previous tests. + // We trace the creation of the object that is being supplied as + // the input to the method under test. There must be one non-null + // assignment only, and usually looks like this: + // this = &tmp_object_factory$1; const irep_idt &this_tmp_name = require_goto_statements::require_entry_point_argument_assignment( "this", entry_point_code); THEN("Object 'this' created has unspecialized inherited field") { + // tmp_object_factory$1.@UnsupportedWrapper1.field = + // &tmp_object_factory$2; + // struct java.lang.Object { __CPROVER_string @class_identifier; + // boolean @lock; } tmp_object_factory$2; require_goto_statements::require_struct_component_assignment( this_tmp_name, {"UnsupportedWrapper1"}, @@ -466,23 +473,18 @@ SCENARIO( "marked as generic)") { const symbol_tablet &symbol_table = load_java_class( - "SuperclassMocked", + "SuperclassOpaque", "./goto-programs/goto_program_generics", - "SuperclassMocked.foo"); + "SuperclassOpaque.foo"); - THEN("The struct for MockedWrapper is incomplete and not-generic") + THEN("The struct for OpaqueWrapper is incomplete and not-generic") { - const std::string superclass_name = "java::MockedWrapper"; - REQUIRE(symbol_table.has_symbol(superclass_name)); - + const std::string superclass_name = "java::OpaqueWrapper"; const symbolt &superclass_symbol = - symbol_table.lookup_ref(superclass_name); - const java_class_typet &superclass_type = - to_java_class_type(to_class_type(superclass_symbol.type)); - REQUIRE( - to_class_type(superclass_symbol.type).get_bool(ID_incomplete_class)); - REQUIRE(!is_java_generic_class_type(superclass_type)); - REQUIRE(!is_java_implicitly_generic_class_type(superclass_type)); + require_symbol::require_symbol_exists(symbol_table, superclass_name); + + require_type::require_incomplete_class(superclass_symbol.type); + require_type::require_java_non_generic_class(superclass_symbol.type); } WHEN("The method input argument is created in the entry point function") @@ -500,7 +502,7 @@ SCENARIO( { require_goto_statements::require_struct_component_assignment( this_tmp_name, - {"MockedWrapper"}, + {"OpaqueWrapper"}, "field", "java::java.lang.Object", {}, diff --git a/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp b/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp index b01c9f6194d..731b577423c 100644 --- a/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp +++ b/unit/goto-programs/goto_program_generics/generic_parameters_test.cpp @@ -10,6 +10,7 @@ #include #include #include +#include // NOTE: To inspect these tests at any point, use expr2java. // A good way to verify the validity of a test is to iterate @@ -504,18 +505,20 @@ SCENARIO( THEN("The struct for UnsupportedWrapper2 is complete and non-generic") { - const std::string superclass_name = "java::UnsupportedWrapper2"; - REQUIRE(symbol_table.has_symbol(superclass_name)); - + const std::string field_class_name = "java::UnsupportedWrapper2"; const symbolt &superclass_symbol = - symbol_table.lookup_ref(superclass_name); - require_type::require_java_non_generic_class(superclass_symbol.type); + require_symbol::require_symbol_exists(symbol_table, field_class_name); + + require_type::require_complete_java_non_generic_class( + superclass_symbol.type); } WHEN("The method input argument is created in the entry point function") { - // For an explanation of this part, look at the comments for the similar - // parts of the previous tests. + // We trace the creation of the object that is being supplied as + // the input to the method under test. There must be one non-null + // assignment only, and usually looks like this: + // this = &tmp_object_factory$1; const std::vector &entry_point_code = require_goto_statements::require_entry_point_statements(symbol_table); @@ -525,6 +528,10 @@ SCENARIO( THEN("Object 'this' has field 'f' of type UnsupportedWrapper2") { + // tmp_object_factory$1.f = &tmp_object_factory$2; + // struct UnsupportedWrapper2 { struct java.lang.Object + // @java.lang.Object; struct java.lang.Object *field; } + // tmp_object_factory$2; const auto &field_input_name = require_goto_statements::require_struct_component_assignment( tmp_object_name, @@ -536,6 +543,9 @@ SCENARIO( THEN("Object 'f' has unspecialized field 'field'") { + // tmp_object_factory$2.field = &tmp_object_factory$3; + // struct java.lang.Object { __CPROVER_string @class_identifier; + // boolean @lock; } tmp_object_factory$3; require_goto_statements::require_struct_component_assignment( field_input_name, {}, @@ -553,23 +563,18 @@ SCENARIO( "incomplete and not marked as generic)") { const symbol_tablet &symbol_table = load_java_class( - "GenericFieldMocked", + "GenericFieldOpaque", "./goto-programs/goto_program_generics", - "GenericFieldMocked.foo"); + "GenericFieldOpaque.foo"); - THEN("The struct for MockedWrapper is incomplete and not-generic") + THEN("The struct for OpaqueWrapper is incomplete and not-generic") { - const std::string superclass_name = "java::MockedWrapper"; - REQUIRE(symbol_table.has_symbol(superclass_name)); + const std::string field_class_name = "java::OpaqueWrapper"; + const symbolt &field_class_symbol = + require_symbol::require_symbol_exists(symbol_table, field_class_name); - const symbolt &superclass_symbol = - symbol_table.lookup_ref(superclass_name); - const java_class_typet &superclass_type = - to_java_class_type(to_class_type(superclass_symbol.type)); - REQUIRE( - to_class_type(superclass_symbol.type).get_bool(ID_incomplete_class)); - REQUIRE(!is_java_generic_class_type(superclass_type)); - REQUIRE(!is_java_implicitly_generic_class_type(superclass_type)); + require_type::require_incomplete_class(field_class_symbol.type); + require_type::require_java_non_generic_class(field_class_symbol.type); } WHEN("The method input argument is created in the entry point function") @@ -583,14 +588,14 @@ SCENARIO( require_goto_statements::require_entry_point_argument_assignment( "this", entry_point_code); - THEN("Object 'this' has field 'f' of type MockedWrapper") + THEN("Object 'this' has field 'f' of type OpaqueWrapper") { const auto &field_input_name = require_goto_statements::require_struct_component_assignment( tmp_object_name, {}, "f", - "java::MockedWrapper", + "java::OpaqueWrapper", {}, entry_point_code); From 076aa5aa4ec3dc61c9a4598956bff6a42cbd2060 Mon Sep 17 00:00:00 2001 From: svorenova Date: Fri, 23 Mar 2018 11:09:35 +0000 Subject: [PATCH 8/8] Improving warnings for unsupported signatures for generics cont. --- .../java_bytecode_convert_class.cpp | 6 +++--- .../java_bytecode_convert_method.cpp | 17 ++++++++++------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/java_bytecode/java_bytecode_convert_class.cpp b/src/java_bytecode/java_bytecode_convert_class.cpp index 317c4f3c361..93a473cf9b4 100644 --- a/src/java_bytecode/java_bytecode_convert_class.cpp +++ b/src/java_bytecode/java_bytecode_convert_class.cpp @@ -202,7 +202,7 @@ void java_bytecode_convert_classt::convert(const classt &c) } class_type=generic_class_type; } - catch(unsupported_java_class_signature_exceptiont &e) + catch(const unsupported_java_class_signature_exceptiont &e) { warning() << "Class: " << c.name << "\n could not parse signature: " << c.signature.value() @@ -255,7 +255,7 @@ void java_bytecode_convert_classt::convert(const classt &c) base, superclass_ref.value(), qualified_classname); class_type.add_base(generic_base); } - catch(unsupported_java_class_signature_exceptiont &e) + catch(const unsupported_java_class_signature_exceptiont &e) { warning() << "Superclass: " << c.extends << " of class: " << c.name << "\n could not parse signature: " << superclass_ref.value() @@ -295,7 +295,7 @@ void java_bytecode_convert_classt::convert(const classt &c) base, interface_ref.value(), qualified_classname); class_type.add_base(generic_base); } - catch(unsupported_java_class_signature_exceptiont &e) + catch(const unsupported_java_class_signature_exceptiont &e) { warning() << "Interface: " << interface << " of class: " << c.name << "\n could not parse signature: " << interface_ref.value() diff --git a/src/java_bytecode/java_bytecode_convert_method.cpp b/src/java_bytecode/java_bytecode_convert_method.cpp index 7d19ac2e7d7..7d4007add8a 100644 --- a/src/java_bytecode/java_bytecode_convert_method.cpp +++ b/src/java_bytecode/java_bytecode_convert_method.cpp @@ -287,17 +287,20 @@ code_typet member_type_lazy( else { message.warning() << "Method: " << class_name << "." << method_name - << "\n signature: " << signature.value() << "\n descriptor: " - << descriptor << "\n different number of parameters, reverting to " - "descriptor" << message.eom; + << "\n signature: " << signature.value() + << "\n descriptor: " << descriptor + << "\n different number of parameters, reverting to " + "descriptor" + << message.eom; } } - catch(unsupported_java_class_signature_exceptiont &e) + catch(const unsupported_java_class_signature_exceptiont &e) { message.warning() << "Method: " << class_name << "." << method_name - << "\n could not parse signature: " << signature.value() << "\n " - << e.what() << "\n" << " reverting to descriptor: " - << descriptor << message.eom; + << "\n could not parse signature: " << signature.value() + << "\n " << e.what() << "\n" + << " reverting to descriptor: " << descriptor + << message.eom; } } return to_code_type(member_type_from_descriptor);