@@ -35,6 +35,8 @@ Author: Daniel Kroening, kroening@kroening.com
3535#include " java_types.h"
3636#include " java_utils.h"
3737
38+ #define JAVA_MAIN_METHOD " main:([Ljava/lang/String;)V"
39+
3840static void create_initialize (symbol_table_baset &symbol_table)
3941{
4042 // If __CPROVER_initialize already exists, replace it. It may already exist
@@ -145,6 +147,27 @@ static void java_static_lifetime_init(
145147 }
146148}
147149
150+ // / Checks whether the given symbol is a valid java main method
151+ // / i.e. it must be public, static, called 'main' and
152+ // / have signature void(String[])
153+ // / \param function: the function symbol
154+ // / \return true if it is a valid main method
155+ bool is_java_main (const symbolt &function)
156+ {
157+ bool named_main = has_suffix (id2string (function.name ), JAVA_MAIN_METHOD);
158+ const code_typet &function_type = to_code_type (function.type );
159+ const typet &string_array_type = java_type_from_string (" [Ljava/lang/String;" );
160+ // checks whether the function is static and has a single String[] parameter
161+ bool is_static = !function_type.has_this ();
162+ // this should be implied by the signature
163+ const code_typet::parameterst ¶meters = function_type.parameters ();
164+ bool has_correct_type = function_type.return_type ().id () == ID_empty &&
165+ parameters.size () == 1 &&
166+ parameters[0 ].type ().full_eq (string_array_type);
167+ bool public_access = function_type.get (ID_access) == ID_public;
168+ return named_main && is_static && has_correct_type && public_access;
169+ }
170+
148171// / Extends \p init_code with code that allocates the objects used as test
149172// / arguments for the function under test (\p function) and
150173// / non-deterministically initializes them.
@@ -171,24 +194,7 @@ exprt::operandst java_build_arguments(
171194 // certain method arguments cannot be allowed to be null, we set the following
172195 // variable to true iff the method under test is the "main" method, which will
173196 // be called (by the jvm) with arguments that are never null
174- bool is_default_entry_point (config.main .empty ());
175- bool is_main=is_default_entry_point;
176-
177- // if walks like a duck and quacks like a duck, it is a duck!
178- if (!is_main)
179- {
180- bool named_main=has_suffix (config.main , " .main" );
181- const typet &string_array_type=
182- java_type_from_string (" [Ljava.lang.String;" );
183- // checks whether the function is static and has a single String[] parameter
184- bool has_correct_type=
185- to_code_type (function.type ).return_type ().id ()==ID_empty &&
186- (!to_code_type (function.type ).has_this ()) &&
187- parameters.size ()==1 &&
188- parameters[0 ].type ().full_eq (string_array_type);
189- bool public_access = function.type .get (ID_access) == ID_public;
190- is_main=(named_main && has_correct_type && public_access);
191- }
197+ bool is_main = is_java_main (function);
192198
193199 // we iterate through all the parameters of the function under test, allocate
194200 // an object for that parameter (recursively allocating other objects
@@ -359,35 +365,14 @@ main_function_resultt get_main_symbol(
359365 if (main_class.empty ())
360366 return main_function_resultt::NotFound; // silently ignore
361367
362- std::string entry_method = id2string (main_class) + " .main" ;
363-
364- std::string prefix=" java::" +entry_method+" :" ;
365-
366- // look it up
367- std::set<const symbolt *> matches;
368+ std::string entry_method =
369+ " java::" + id2string (main_class) + " ." + JAVA_MAIN_METHOD;
370+ const symbolt *symbol = symbol_table.lookup (entry_method);
368371
369- for (const auto &named_symbol : symbol_table.symbols )
370- {
371- if (named_symbol.second .type .id () == ID_code
372- && has_prefix (id2string (named_symbol.first ), prefix))
373- {
374- matches.insert (&named_symbol.second );
375- }
376- }
377-
378- if (matches.empty ())
379- // Not found, silently ignore
380- return main_function_resultt::NotFound;
381-
382- if (matches.size () > 1 )
383- {
384- message.error ()
385- << " main method in `" << main_class
386- << " ' is ambiguous" << messaget::eom;
387- return main_function_resultt::Error; // give up with error, no main
388- }
372+ if (!symbol || !is_java_main (*symbol))
373+ return main_function_resultt::Error; // give up with error, no main
389374
390- return **matches. begin (); // Return found function
375+ return *symbol;
391376 }
392377}
393378
0 commit comments