The spaghetti code in PR fortran/91359 has a few gotos to jump to different places. In doing so, gfortran with generate a function that has a naked 'return'. Namely,
foo () { logical(kind=4) __result_foo; goto __label_000002; __label_000001:; return; /* <-- THIS IS BAD. */ __label_000002:; __result_foo = 0; if (!__result_foo) goto __label_000001; L.1:; return __result_foo; return __result_foo; } The attached patch avoids the naked 'return' by adding the variable that is constructed from the the function name. Namely, foo () { logical(kind=4) __result_foo; goto __label_000002; __label_000001:; return __result_foo; /* <-- THIS IS GOOD. */ __label_000002:; __result_foo = 0; if (!__result_foo) goto __label_000001; L.1:; return __result_foo; return __result_foo; } Regression tested on x86_64-*-freebsd. OK to commit? 2019-08-06 Steven G. Kargl <ka...@gcc.gnu.org> PR fortran/91359 * trans-decl.c (gfc_generate_return): Ensure something is returned from a function. 2019-08-06 Steven G. Kargl <ka...@gcc.gnu.org> PR fortran/91359 * gfortran.dg/pr91359_1.f: New test. * gfortran.dg/pr91359_2.f: Ditto. -- Steve
Index: gcc/fortran/trans-decl.c =================================================================== --- gcc/fortran/trans-decl.c (revision 274121) +++ gcc/fortran/trans-decl.c (working copy) @@ -6449,6 +6449,20 @@ gfc_generate_return (void) TREE_TYPE (result), DECL_RESULT (fndecl), result); } + else + { + /* If the function does not have a result variable, result is + NULL_TREE, and a 'return' is generated without a variable. + The following generates a 'return __result_XXX' where XXX is + the function name. */ + if (sym == sym->result && sym->attr.function) + { + result = gfc_get_fake_result_decl (sym, 0); + result = fold_build2_loc (input_location, MODIFY_EXPR, + TREE_TYPE (result), + DECL_RESULT (fndecl), result); + } + } } return build1_v (RETURN_EXPR, result); Index: gcc/testsuite/gfortran.dg/pr91359_1.f =================================================================== --- gcc/testsuite/gfortran.dg/pr91359_1.f (nonexistent) +++ gcc/testsuite/gfortran.dg/pr91359_1.f (working copy) @@ -0,0 +1,17 @@ +! { dg do } +! PR fortran/91359 +! Orginal code contributed by Brian T. Carcich <briantcarcich at gmail dot com> +! + logical function zero() result(a) + goto 2 +1 return +2 a = .false. + if (.not.a) goto 1 + return + end + + program test_zero + logical zero + if (zero()) stop 'FAIL: zero() returned .TRUE.' + stop 'OKAY: zero() returned .FALSE.' + end Index: gcc/testsuite/gfortran.dg/pr91359_2.f =================================================================== --- gcc/testsuite/gfortran.dg/pr91359_2.f (nonexistent) +++ gcc/testsuite/gfortran.dg/pr91359_2.f (working copy) @@ -0,0 +1,17 @@ +! { dg do } +! PR fortran/91359 +! Orginal code contributed by Brian T. Carcich <briantcarcich at gmail dot com> +! + logical function zero() result(a) + goto 2 +1 return +2 a = .false. + if (.not.a) goto 1 + return + end + + program test_zero + logical zero + if (zero()) stop 'FAIL: zero() returned .TRUE.' + stop 'OKAY: zero() returned .FALSE.' + end