In gfc_get_symbol_decl, if an external procedure is invoked and sym->backend_decl is NULL_TREE, gfc_get_extern_function_decl is called. This searches the translation unit (or gsym) to find the declaration – and if found, it returns it.
Well, that worked and the module procedure's decl is returned with DECL_SOURCE_LOCATION() matching the original declaration and the associated cfun->function_end_location is also properly set. But before this patch, the location is reset to the sym->declared_at, which is the location of the "use foo" line in the example from the PR. Result: The DECL_SOURCE_LOCATION(cfun->decl) is *after* cfun->function_end_location, which runs with --coverage into an assert. The other changes to BIND_EXPR is unrelated. It was just that I did run with '-fdump-tree-original-lineno' and got: foo_suite () [coverage.f90:17:22] { integer(kind=4) res; [coverage.f90:16:17] res = bar ([coverage.f90:16:17] sbr); } Where line 17 for '{' looked odd. With the patch, we now have: foo_suite () [coverage.f90:12:0] { integer(kind=4) res; [coverage.f90:16:17] res = bar ([coverage.f90:16:17] sbr); } OK for the trunk? Tobias ----------------- Mentor Graphics (Deutschland) GmbH, Arnulfstraße 201, 80634 München / Germany Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Alexander Walter
Fortran: Fix function decl's location [PR95847] gcc/fortran/ChangeLog: PR fortran/95847 * trans-decl.c (gfc_get_symbol_decl): Do not (re)set the location of an external procedure. (build_entry_thunks, generate_coarray_init, create_main_function, gfc_generate_function_code): Use fndecl's location in BIND_EXPR. gcc/testsuite/ChangeLog: PR fortran/95847 * gfortran.dg/coverage.f90: New test. gcc/fortran/trans-decl.c | 19 ++++++++++--------- gcc/testsuite/gfortran.dg/coverage.f90 | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index cdef753ea8d..71d5c670e55 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -1749,7 +1749,6 @@ gfc_get_symbol_decl (gfc_symbol * sym) || sym->attr.if_source != IFSRC_DECL) { decl = gfc_get_extern_function_decl (sym); - gfc_set_decl_location (decl, &sym->declared_at); } else { @@ -3021,8 +3020,9 @@ build_entry_thunks (gfc_namespace * ns, bool global) poplevel (1, 1); BLOCK_SUPERCONTEXT (DECL_INITIAL (thunk_fndecl)) = thunk_fndecl; DECL_SAVED_TREE (thunk_fndecl) - = build3_v (BIND_EXPR, tmp, DECL_SAVED_TREE (thunk_fndecl), - DECL_INITIAL (thunk_fndecl)); + = fold_build3_loc (DECL_SOURCE_LOCATION (thunk_fndecl), BIND_EXPR, + void_type_node, tmp, DECL_SAVED_TREE (thunk_fndecl), + DECL_INITIAL (thunk_fndecl)); /* Output the GENERIC tree. */ dump_function (TDI_original, thunk_fndecl); @@ -5786,8 +5786,8 @@ generate_coarray_init (gfc_namespace * ns __attribute((unused))) BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; DECL_SAVED_TREE (fndecl) - = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl), - DECL_INITIAL (fndecl)); + = fold_build3_loc (DECL_SOURCE_LOCATION (fndecl), BIND_EXPR, void_type_node, + decl, DECL_SAVED_TREE (fndecl), DECL_INITIAL (fndecl)); dump_function (TDI_original, fndecl); cfun->function_end_locus = input_location; @@ -6512,8 +6512,9 @@ create_main_function (tree fndecl) BLOCK_SUPERCONTEXT (DECL_INITIAL (ftn_main)) = ftn_main; DECL_SAVED_TREE (ftn_main) - = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (ftn_main), - DECL_INITIAL (ftn_main)); + = fold_build3_loc (DECL_SOURCE_LOCATION (ftn_main), BIND_EXPR, + void_type_node, decl, DECL_SAVED_TREE (ftn_main), + DECL_INITIAL (ftn_main)); /* Output the GENERIC tree. */ dump_function (TDI_original, ftn_main); @@ -7004,8 +7005,8 @@ gfc_generate_function_code (gfc_namespace * ns) BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; DECL_SAVED_TREE (fndecl) - = build3_v (BIND_EXPR, decl, DECL_SAVED_TREE (fndecl), - DECL_INITIAL (fndecl)); + = fold_build3_loc (DECL_SOURCE_LOCATION (fndecl), BIND_EXPR, void_type_node, + decl, DECL_SAVED_TREE (fndecl), DECL_INITIAL (fndecl)); /* Output the GENERIC tree. */ dump_function (TDI_original, fndecl); diff --git a/gcc/testsuite/gfortran.dg/coverage.f90 b/gcc/testsuite/gfortran.dg/coverage.f90 new file mode 100644 index 00000000000..e0800f869c1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/coverage.f90 @@ -0,0 +1,17 @@ +! { dg-do compile } +! { dg-additional-options "-fprofile-arcs -ftest-coverage" } +! +! PR fortran/95847 +! +module foo +contains + subroutine sbr() + end subroutine sbr +end module foo + +function foo_suite() result(suite) + use foo + integer :: bar + integer :: res + res = bar(sbr) +end function foo_suite