22
22
#include " java_string_literals.h"
23
23
#include " java_utils.h"
24
24
25
+ #define JAVA_MAIN_METHOD " main:([Ljava/lang/String;)V"
26
+
25
27
static void create_initialize (symbol_table_baset &symbol_table)
26
28
{
27
29
// If __CPROVER_initialize already exists, replace it. It may already exist
@@ -242,6 +244,27 @@ static void java_static_lifetime_init(
242
244
}
243
245
}
244
246
247
+ // / Checks whether the given symbol is a valid java main method
248
+ // / i.e. it must be public, static, called 'main' and
249
+ // / have signature void(String[])
250
+ // / \param function: the function symbol
251
+ // / \return true if it is a valid main method
252
+ bool is_java_main (const symbolt &function)
253
+ {
254
+ bool named_main = has_suffix (id2string (function.name ), JAVA_MAIN_METHOD);
255
+ const code_typet &function_type = to_code_type (function.type );
256
+ const typet &string_array_type = java_type_from_string (" [Ljava/lang/String;" );
257
+ // checks whether the function is static and has a single String[] parameter
258
+ bool is_static = !function_type.has_this ();
259
+ // this should be implied by the signature
260
+ const code_typet::parameterst ¶meters = function_type.parameters ();
261
+ bool has_correct_type = function_type.return_type ().id () == ID_empty &&
262
+ parameters.size () == 1 &&
263
+ parameters[0 ].type ().full_eq (string_array_type);
264
+ bool public_access = function_type.get (ID_access) == ID_public;
265
+ return named_main && is_static && has_correct_type && public_access;
266
+ }
267
+
245
268
// / Extends \p init_code with code that allocates the objects used as test
246
269
// / arguments for the function under test (\p function) and
247
270
// / non-deterministically initializes them.
@@ -268,24 +291,7 @@ exprt::operandst java_build_arguments(
268
291
// certain method arguments cannot be allowed to be null, we set the following
269
292
// variable to true iff the method under test is the "main" method, which will
270
293
// be called (by the jvm) with arguments that are never null
271
- bool is_default_entry_point (config.main .empty ());
272
- bool is_main=is_default_entry_point;
273
-
274
- // if walks like a duck and quacks like a duck, it is a duck!
275
- if (!is_main)
276
- {
277
- bool named_main=has_suffix (config.main , " .main" );
278
- const typet &string_array_type=
279
- java_type_from_string (" [Ljava.lang.String;" );
280
- // checks whether the function is static and has a single String[] parameter
281
- bool has_correct_type=
282
- to_code_type (function.type ).return_type ().id ()==ID_empty &&
283
- (!to_code_type (function.type ).has_this ()) &&
284
- parameters.size ()==1 &&
285
- parameters[0 ].type ().full_eq (string_array_type);
286
- bool public_access = function.type .get (ID_access) == ID_public;
287
- is_main = named_main && has_correct_type && public_access;
288
- }
294
+ bool is_main = is_java_main (function);
289
295
290
296
// we iterate through all the parameters of the function under test, allocate
291
297
// an object for that parameter (recursively allocating other objects
@@ -455,37 +461,25 @@ main_function_resultt get_main_symbol(
455
461
456
462
// are we given a main class?
457
463
if (main_class.empty ())
458
- return main_function_resultt::NotFound; // silently ignore
459
-
460
- std::string entry_method = id2string (main_class) + " .main" ;
461
-
462
- std::string prefix=" java::" +entry_method+" :" ;
463
-
464
- // look it up
465
- std::set<const symbolt *> matches;
466
-
467
- for (const auto &named_symbol : symbol_table.symbols )
468
464
{
469
- if (named_symbol.second .type .id () == ID_code
470
- && has_prefix (id2string (named_symbol.first ), prefix))
471
- {
472
- matches.insert (&named_symbol.second );
473
- }
465
+ // no, but we allow this situation to output symbol table,
466
+ // goto functions, etc
467
+ return main_function_resultt::NotFound;
474
468
}
475
469
476
- if (matches. empty ())
477
- // Not found, silently ignore
478
- return main_function_resultt::NotFound ;
470
+ std::string entry_method =
471
+ " java:: " + id2string (main_class) + " . " + JAVA_MAIN_METHOD;
472
+ const symbolt *symbol = symbol_table. lookup (entry_method) ;
479
473
480
- if (matches.size () > 1 )
474
+ // has the class a correct main method?
475
+ if (!symbol || !is_java_main (*symbol))
481
476
{
482
- message.error ()
483
- << " main method in `" << main_class
484
- << " ' is ambiguous" << messaget::eom;
485
- return main_function_resultt::Error; // give up with error, no main
477
+ // no, but we allow this situation to output symbol table,
478
+ // goto functions, etc
479
+ return main_function_resultt::NotFound;
486
480
}
487
481
488
- return **matches. begin (); // Return found function
482
+ return *symbol;
489
483
}
490
484
}
491
485
0 commit comments