Skip to content

Commit 272ba02

Browse files
authored
Merge pull request #4258 from smowton/smowton/fix/java-fake-stubs-parameter-identifiers
Java frontend: treat CProver stubbed methods more like normal stubs
2 parents df2b3ca + 4c724de commit 272ba02

File tree

7 files changed

+57
-44
lines changed

7 files changed

+57
-44
lines changed
292 Bytes
Binary file not shown.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
public class Test {
2+
3+
public static void main() {
4+
5+
org.cprover.CProver.startThread(1);
6+
7+
}
8+
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CORE
2+
Test.class
3+
--function Test.main --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar`
4+
^VERIFICATION SUCCESSFUL$
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
--
9+
This calls CProver.startThread, which is special-cased by the Java front-end (which omits the method's body
10+
in hope of the front-end handling it like a stub), and doesn't get its parameter names assigned by the usual
11+
mechanism (setting the names when the stub is discovered for the first time)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
Test.class
3+
--function Test.main --cp `../../../../scripts/format_classpath.sh . ../../../lib/java-models-library/target/core-models.jar` --show-goto-functions
4+
org\.cprover\.CProver\.startThread:\(I\)V
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
--
8+
--
9+
Companion to the main test.desc that checks the function under test uses org.cprover.CProver.startThread(int)

jbmc/src/java_bytecode/java_bytecode_convert_class.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,13 @@ class java_bytecode_convert_classt:public messaget
138138
return method.has_annotation(ID_overlay_method);
139139
}
140140

141-
/// Check if a method is an ignored method by searching for
142-
/// `ID_ignored_method` in its list of annotations.
141+
/// Check if a method is an ignored method, by one of two mechanisms:
143142
///
144-
/// An ignored method is a method with the annotation
145-
/// \@IgnoredMethodImplementation. They will be ignored by JBMC. They are
146-
/// intended for use in
143+
/// 1. If the class under consideration is org.cprover.CProver, and the method
144+
/// is listed as ignored.
145+
///
146+
/// 2. If it has the annotation\@IgnoredMethodImplementation.
147+
/// This kind of ignord method is intended for use in
147148
/// [overlay classes](\ref java_class_loader.cpp::is_overlay_class), in
148149
/// particular for methods which must exist in the overlay class so that
149150
/// it will compile, e.g. default constructors, but which we do not want
@@ -154,11 +155,17 @@ class java_bytecode_convert_classt:public messaget
154155
/// [overlay method](\ref java_bytecode_convert_classt::is_overlay_method)
155156
/// or an ignored method.
156157
///
158+
/// \param class_name: class the method is declared on
157159
/// \param method: a `methodt` object from a java bytecode parse tree
158160
/// \return true if the method is an ignored method, else false
159-
static bool is_ignored_method(const methodt &method)
161+
static bool is_ignored_method(
162+
const irep_idt &class_name, const methodt &method)
160163
{
161-
return method.has_annotation(ID_ignored_method);
164+
static irep_idt org_cprover_CProver_name = "org.cprover.CProver";
165+
return
166+
(class_name == org_cprover_CProver_name &&
167+
cprover_methods_to_ignore.count(id2string(method.name)) != 0) ||
168+
method.has_annotation(ID_ignored_method);
162169
}
163170

164171
bool check_field_exists(
@@ -504,7 +511,7 @@ void java_bytecode_convert_classt::convert(
504511
const irep_idt method_identifier =
505512
qualified_classname + "." + id2string(method.name)
506513
+ ":" + method.descriptor;
507-
if(is_ignored_method(method))
514+
if(is_ignored_method(c.name, method))
508515
{
509516
debug()
510517
<< "Ignoring method: '" << method_identifier << "'"
@@ -552,7 +559,7 @@ void java_bytecode_convert_classt::convert(
552559
const irep_idt method_identifier=
553560
qualified_classname + "." + id2string(method.name)
554561
+ ":" + method.descriptor;
555-
if(is_ignored_method(method))
562+
if(is_ignored_method(c.name, method))
556563
{
557564
debug()
558565
<< "Ignoring method: '" << method_identifier << "'"

jbmc/src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,15 @@ void java_bytecode_convert_method_lazy(
398398
symbol_table.add(method_symbol);
399399
}
400400

401+
static irep_idt get_method_identifier(
402+
const irep_idt &class_identifier,
403+
const java_bytecode_parse_treet::methodt &method)
404+
{
405+
return
406+
id2string(class_identifier) + "." + id2string(method.name) + ":" +
407+
method.descriptor;
408+
}
409+
401410
void java_bytecode_convert_methodt::convert(
402411
const symbolt &class_symbol,
403412
const methodt &m)
@@ -406,8 +415,9 @@ void java_bytecode_convert_methodt::convert(
406415
// (e.g. "my.package.ClassName.myMethodName:(II)I") and query the symbol table
407416
// to retrieve the symbol (constructed by java_bytecode_convert_method_lazy)
408417
// associated to the method
409-
const irep_idt method_identifier=
410-
id2string(class_symbol.name)+"."+id2string(m.name)+":"+m.descriptor;
418+
const irep_idt method_identifier =
419+
get_method_identifier(class_symbol.name, m);
420+
411421
method_id=method_identifier;
412422

413423
// Obtain a std::vector of java_method_typet::parametert objects from the
@@ -3077,16 +3087,6 @@ void java_bytecode_convert_method(
30773087
bool threading_support)
30783088

30793089
{
3080-
if(std::regex_match(
3081-
id2string(class_symbol.name),
3082-
std::regex(".*org\\.cprover\\.CProver.*")) &&
3083-
cprover_methods_to_ignore.count(id2string(method.name)))
3084-
{
3085-
// Ignore these methods; fall back to the driver program's
3086-
// stubbing behaviour.
3087-
return;
3088-
}
3089-
30903090
java_bytecode_convert_methodt java_bytecode_convert_method(
30913091
symbol_table,
30923092
message_handler,

jbmc/src/java_bytecode/java_bytecode_language.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -933,30 +933,7 @@ void java_bytecode_languaget::methods_provided(
933933
string_preprocess.get_all_function_names(methods);
934934
// Add all concrete methods to map
935935
for(const auto &kv : method_bytecode)
936-
{
937-
const std::string &method_id = id2string(kv.first);
938-
939-
// Avoid advertising org.cprover.CProver methods that the Java frontend will
940-
// never provide bodies for (java_bytecode_convert_method always leaves them
941-
// bodyless with intent for the driver program to stub them):
942-
if(has_prefix(method_id, cprover_class_prefix))
943-
{
944-
std::size_t method_name_end_offset =
945-
method_id.find(':', cprover_class_prefix.length());
946-
INVARIANT(
947-
method_name_end_offset != std::string::npos,
948-
"org.cprover.CProver method should have a postfix type descriptor");
949-
950-
const std::string method_name =
951-
method_id.substr(
952-
cprover_class_prefix.length(),
953-
method_name_end_offset - cprover_class_prefix.length());
954-
955-
if(cprover_methods_to_ignore.count(method_name))
956-
continue;
957-
}
958936
methods.insert(kv.first);
959-
}
960937
// Add all synthetic methods to map
961938
for(const auto &kv : synthetic_methods)
962939
methods.insert(kv.first);

0 commit comments

Comments
 (0)