From 14e087355085aee1ccf332f6f6408da19eea7760 Mon Sep 17 00:00:00 2001 From: Michael Tautschnig Date: Sat, 29 Nov 2025 20:38:04 +0100 Subject: [PATCH] Fix virtual method resolution for Java Object parameters The skip condition for avoiding re-processing of already-visited classes had inverted logic. Fixes: #930 --- .../SimpleEquals.class | Bin 0 -> 890 bytes .../SimpleEquals.java | 22 ++++++++++++++++++ .../equals_Pass.class | Bin 0 -> 867 bytes .../equals_Pass.java | 13 +++++++++++ .../simple_test.desc | 9 +++++++ .../virtual_equals_object_param/test.desc | 9 +++++++ .../remove_virtual_functions.cpp | 9 ++++--- 7 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 jbmc/regression/jbmc/virtual_equals_object_param/SimpleEquals.class create mode 100644 jbmc/regression/jbmc/virtual_equals_object_param/SimpleEquals.java create mode 100644 jbmc/regression/jbmc/virtual_equals_object_param/equals_Pass.class create mode 100644 jbmc/regression/jbmc/virtual_equals_object_param/equals_Pass.java create mode 100644 jbmc/regression/jbmc/virtual_equals_object_param/simple_test.desc create mode 100644 jbmc/regression/jbmc/virtual_equals_object_param/test.desc diff --git a/jbmc/regression/jbmc/virtual_equals_object_param/SimpleEquals.class b/jbmc/regression/jbmc/virtual_equals_object_param/SimpleEquals.class new file mode 100644 index 0000000000000000000000000000000000000000..3adeca6f588ec63595f35db7c52a7e503e7a57da GIT binary patch literal 890 zcmZvaUvJV-7{;GN3x(1NErX$gx;Y(x=J3MAixK0p%^R5}vXIEG3Yog?I={Y^``MuBcoc{Xr?FWDzJXVo_q(Ih?M2aDQY<@6Xw&{#p zuLs9`7%-&TmSY9a7^GUgmqwZ)IpMbLW}qUgK+~{<8w^_4nx5Ev|9xoMK0{&M^nLCH zmh1R?mTwMhK4M^f6?y0i3=IV=|I@DsPZS2a2#|t;3esrMmn_(CR21atAwJzo#BWFZm6%*!NWOHW zp+t@ZQ35Lwsfo>q^pr>vZRE~z)2MWe%0YAU9Cu=SCDH|IFTo&f1v- literal 0 HcmV?d00001 diff --git a/jbmc/regression/jbmc/virtual_equals_object_param/SimpleEquals.java b/jbmc/regression/jbmc/virtual_equals_object_param/SimpleEquals.java new file mode 100644 index 00000000000..0bbcfdbcd6f --- /dev/null +++ b/jbmc/regression/jbmc/virtual_equals_object_param/SimpleEquals.java @@ -0,0 +1,22 @@ +// Simpler test case demonstrating the virtual method resolution bug +public class SimpleEquals { + public static void testDirect() { + // Direct call on String - this works + String s1 = "hello"; + String s2 = "hello"; + assert(s1.equals(s2)); + } + + public static void testThroughObject(Object o1, Object o2) { + // Call through Object parameter - this was failing before the fix + assert(o1.equals(o2)); + } + + public static void main(String[] args) { + testDirect(); + + String s1 = "world"; + String s2 = "world"; + testThroughObject(s1, s2); + } +} diff --git a/jbmc/regression/jbmc/virtual_equals_object_param/equals_Pass.class b/jbmc/regression/jbmc/virtual_equals_object_param/equals_Pass.class new file mode 100644 index 0000000000000000000000000000000000000000..5246bc17974423f8f8c300f9d953c890155105f0 GIT binary patch literal 867 zcmZuv-*3`T7(JI3+O?e&*nrL9&*^~T_Mk6@WpSDFMW!a0CBp|(%FWVQinhhXf5LZp zUwrXJO~ANB-}d0&q{i<816_)+V_icGk^;V$bM^Y zc(#AI@w9oworoc^>H2Q8#UK?+`=VSmFb9nm_?xcng$#?u+WBqOQbU39A6`8QT>ntT zB|@^Bjs_j3U`?F^7}Zrv`*X-(LBXPdEOHF`i0&0M#jV<(!S|<PT>g4i8{vUKmQ53?@#U{h zQL->IFQkvymx&WlNVJ Zsecond.children) { // Skip if we have already visited this and we found a function call that - // did not resolve to non java.lang.Object. + // resolved to a non-Object implementation (i.e., we don't need to revisit). auto it = entry_map.find(child); if( - it != entry_map.end() && - (!it->second.symbol_expr.has_value() || - !it->second.symbol_expr->get_identifier().starts_with( - "java::java.lang.Object"))) + it != entry_map.end() && it->second.symbol_expr.has_value() && + !it->second.symbol_expr->get_identifier().starts_with( + "java::java.lang.Object")) { continue; }