@@ -34,13 +34,13 @@ Author: Daniel Kroening, kroening@kroening.com
3434// / Generate an entry point that calls a function with the given name, based on
3535// / the functions language mode in the symbol table
3636static bool generate_entry_point_for_function (
37- const irep_idt &entry_function_name,
3837 const optionst &options,
39- goto_modelt &goto_model ,
38+ symbol_tablet &symbol_table ,
4039 message_handlert &message_handler)
4140{
42- auto const entry_function_sym =
43- goto_model.symbol_table .lookup (entry_function_name);
41+ const irep_idt &entry_function_name = options.get_option (" function" );
42+ CHECK_RETURN (!entry_function_name.empty ());
43+ auto const entry_function_sym = symbol_table.lookup (entry_function_name);
4444 if (entry_function_sym == nullptr )
4545 {
4646 throw invalid_command_line_argument_exceptiont{
@@ -54,42 +54,23 @@ static bool generate_entry_point_for_function(
5454 CHECK_RETURN (entry_language != nullptr );
5555 entry_language->set_message_handler (message_handler);
5656 entry_language->set_language_options (options);
57- return entry_language->generate_support_functions (goto_model. symbol_table );
57+ return entry_language->generate_support_functions (symbol_table);
5858}
5959
60- goto_modelt initialize_goto_model (
61- const std::vector<std::string> &files,
62- message_handlert &message_handler,
63- const optionst &options)
60+ void initialize_from_source_files (
61+ const std::list<std::string> &sources,
62+ const optionst &options,
63+ language_filest &language_files,
64+ symbol_tablet &symbol_table,
65+ message_handlert &message_handler)
6466{
65- messaget msg (message_handler);
66- if (files.empty ())
67- {
68- throw invalid_command_line_argument_exceptiont (
69- " missing program argument" ,
70- " filename" ,
71- " one or more paths to program files" );
72- }
73-
74- std::list<std::string> binaries, sources;
75-
76- for (const auto &file : files)
77- {
78- if (is_goto_binary (file, message_handler))
79- binaries.push_back (file);
80- else
81- sources.push_back (file);
82- }
67+ if (sources.empty ())
68+ return ;
8369
84- language_filest language_files;
85- language_files.set_message_handler (message_handler);
86-
87- goto_modelt goto_model;
70+ messaget msg (message_handler);
8871
89- if (! sources. empty () )
72+ for ( const auto &filename : sources)
9073 {
91- for (const auto &filename : sources)
92- {
9374 #ifdef _MSC_VER
9475 std::ifstream infile (widen (filename));
9576 #else
@@ -107,8 +88,8 @@ goto_modelt initialize_goto_model(
10788
10889 if (lf.language ==nullptr )
10990 {
110- throw invalid_source_file_exceptiont (
111- " Failed to figure out type of file ' " + filename + ' \' ' ) ;
91+ throw invalid_command_line_argument_exceptiont{
92+ " Failed to figure out type of file" , filename} ;
11293 }
11394
11495 languaget &language=*lf.language ;
@@ -119,75 +100,127 @@ goto_modelt initialize_goto_model(
119100
120101 if (language.parse (infile, filename))
121102 {
122- throw invalid_source_file_exceptiont (" PARSING ERROR" );
103+ throw invalid_input_exceptiont (" PARSING ERROR" );
123104 }
124105
125106 lf.get_modules ();
126107 }
127108
128109 msg.status () << " Converting" << messaget::eom;
129110
130- if (language_files.typecheck (goto_model. symbol_table ))
111+ if (language_files.typecheck (symbol_table))
131112 {
132- throw invalid_source_file_exceptiont (" CONVERSION ERROR" );
113+ throw invalid_input_exceptiont (" CONVERSION ERROR" );
133114 }
134- }
135-
136- if (read_objects_and_link (binaries, goto_model, message_handler))
137- {
138- throw invalid_source_file_exceptiont{
139- " failed to read object or link in files" };
140- }
115+ }
141116
142- bool binaries_provided_start=
143- goto_model.symbol_table .has_symbol (goto_functionst::entry_point ());
117+ void set_up_custom_entry_point (
118+ language_filest &language_files,
119+ symbol_tablet &symbol_table,
120+ const std::function<void (const irep_idt &)> &unload,
121+ const optionst &options,
122+ bool try_mode_lookup,
123+ message_handlert &message_handler)
124+ {
125+ bool binaries_provided_start =
126+ symbol_table.has_symbol (goto_functionst::entry_point ());
144127
145128 bool entry_point_generation_failed=false ;
146129
147130 if (binaries_provided_start && options.is_set (" function" ))
148131 {
132+ // The goto binaries provided already contain a __CPROVER_start
133+ // function that may be tied to a different entry point `function`.
134+ // Hence, we will rebuild the __CPROVER_start function.
135+
149136 // Get the language annotation of the existing __CPROVER_start function.
150- std::unique_ptr<languaget> language = get_entry_point_language (
151- goto_model. symbol_table , options, message_handler);
137+ std::unique_ptr<languaget> language =
138+ get_entry_point_language ( symbol_table, options, message_handler);
152139
153140 // To create a new entry point we must first remove the old one
154- remove_existing_entry_point (goto_model. symbol_table );
141+ remove_existing_entry_point (symbol_table);
155142
156143 // Create the new entry-point
157144 entry_point_generation_failed =
158- language->generate_support_functions (goto_model. symbol_table );
145+ language->generate_support_functions (symbol_table);
159146
160147 // Remove the function from the goto functions so it is copied back in
161148 // from the symbol table during goto_convert
162149 if (!entry_point_generation_failed)
163- goto_model. unload (goto_functionst::entry_point ());
150+ unload (goto_functionst::entry_point ());
164151 }
165152 else if (!binaries_provided_start)
166153 {
167- if (options.is_set (" function" ))
154+ if (try_mode_lookup && options.is_set (" function" ))
168155 {
169156 // no entry point is present; Use the mode of the specified entry function
170157 // to generate one
171158 entry_point_generation_failed = generate_entry_point_for_function (
172- options. get_option ( " function " ), options, goto_model , message_handler);
159+ options, symbol_table , message_handler);
173160 }
174- if (entry_point_generation_failed || !options.is_set (" function" ))
161+ if (
162+ !try_mode_lookup || entry_point_generation_failed ||
163+ !options.is_set (" function" ))
175164 {
176165 // Allow all language front-ends to try to provide the user-specified
177166 // (--function) entry-point, or some language-specific default:
178167 entry_point_generation_failed =
179- language_files.generate_support_functions (goto_model. symbol_table );
168+ language_files.generate_support_functions (symbol_table);
180169 }
181170 }
182171
183172 if (entry_point_generation_failed)
184173 {
185- throw invalid_source_file_exceptiont (" SUPPORT FUNCTION GENERATION ERROR" );
174+ throw invalid_input_exceptiont (" SUPPORT FUNCTION GENERATION ERROR" );
175+ }
176+ }
177+
178+ goto_modelt initialize_goto_model (
179+ const std::vector<std::string> &files,
180+ message_handlert &message_handler,
181+ const optionst &options)
182+ {
183+ messaget msg (message_handler);
184+ if (files.empty ())
185+ {
186+ throw invalid_command_line_argument_exceptiont (
187+ " missing program argument" ,
188+ " filename" ,
189+ " one or more paths to program files" );
190+ }
191+
192+ std::list<std::string> binaries, sources;
193+
194+ for (const auto &file : files)
195+ {
196+ if (is_goto_binary (file, message_handler))
197+ binaries.push_back (file);
198+ else
199+ sources.push_back (file);
186200 }
187201
202+ language_filest language_files;
203+ language_files.set_message_handler (message_handler);
204+
205+ goto_modelt goto_model;
206+
207+ initialize_from_source_files (
208+ sources, options, language_files, goto_model.symbol_table , message_handler);
209+
210+ if (read_objects_and_link (binaries, goto_model, message_handler))
211+ throw incorrect_goto_program_exceptiont{" failed to read/link goto model" };
212+
213+ set_up_custom_entry_point (
214+ language_files,
215+ goto_model.symbol_table ,
216+ [&goto_model](const irep_idt &id) { goto_model.goto_functions .unload (id); },
217+ options,
218+ true ,
219+ message_handler);
220+
188221 if (language_files.final (goto_model.symbol_table ))
189222 {
190- throw invalid_source_file_exceptiont (" FINAL STAGE CONVERSION ERROR" );
223+ throw invalid_input_exceptiont (" FINAL STAGE CONVERSION ERROR" );
191224 }
192225
193226 msg.status () << " Generating GOTO Program" << messaget::eom;
0 commit comments