@@ -175,22 +175,56 @@ pub fn simplify_program(mut program: Program) -> SimpleProgram {
175175 v. clone ( )
176176 } )
177177 . collect :: < Vec < _ > > ( ) ;
178- new_functions. insert (
179- name. clone ( ) ,
180- SimpleFunction {
181- name : name. clone ( ) ,
182- arguments,
183- n_returned_vars : func. n_returned_vars ,
184- instructions : simplified_instructions,
185- } ,
186- ) ;
178+ let simplified_function = SimpleFunction {
179+ name : name. clone ( ) ,
180+ arguments,
181+ n_returned_vars : func. n_returned_vars ,
182+ instructions : simplified_instructions,
183+ } ;
184+ if !func. assume_always_returns {
185+ check_function_always_returns ( & simplified_function) ;
186+ }
187+ new_functions. insert ( name. clone ( ) , simplified_function) ;
187188 const_malloc. map . clear ( ) ;
188189 }
189190 SimpleProgram {
190191 functions : new_functions,
191192 }
192193}
193194
195+ /// Analyzes a simplified function to verify that it returns on each code path.
196+ fn check_function_always_returns ( func : & SimpleFunction ) {
197+ check_block_always_returns ( & func. name , & func. instructions ) ;
198+ }
199+
200+ fn check_block_always_returns ( function_name : & String , instructions : & [ SimpleLine ] ) {
201+ match instructions. last ( ) {
202+ Some ( SimpleLine :: Match { value : _, arms } ) => {
203+ for arm in arms {
204+ check_block_always_returns ( function_name, arm) ;
205+ }
206+ }
207+ Some ( SimpleLine :: IfNotZero {
208+ condition : _,
209+ then_branch,
210+ else_branch,
211+ line_number : _,
212+ } ) => {
213+ check_block_always_returns ( function_name, then_branch) ;
214+ check_block_always_returns ( function_name, else_branch) ;
215+ }
216+ Some ( SimpleLine :: FunctionRet { return_data : _ } ) => {
217+ // good
218+ }
219+ Some ( SimpleLine :: Panic ) => {
220+ // good
221+ }
222+ _ => {
223+ panic ! ( "Cannot prove that function always returns: {function_name}" ) ;
224+ }
225+ }
226+ }
227+
194228/// Analyzes the program to verify that each variable is defined in each context where it is used.
195229fn check_program_scoping ( program : & Program ) {
196230 for ( _, function) in program. functions . iter ( ) {
@@ -1844,6 +1878,7 @@ fn handle_const_arguments_helper(
18441878 inlined : false ,
18451879 body : new_body,
18461880 n_returned_vars : func. n_returned_vars ,
1881+ assume_always_returns : func. assume_always_returns ,
18471882 } ,
18481883 ) ;
18491884 }
0 commit comments