the attached patch runs through gfortran's AST to check for missing location information.
... this time with attachment. 2016-11-14 Thomas Koenig <tkoe...@gcc.gnu.org> PR fortran/78226 * error.c (gfc_warning_internal): New function. * frontend-passes.c (CHECK_LOCUS): New macro. (gfc_run_passes): Call check_locus if CHECK_LOCUS is defined. (check_locus_code): New function. (check_locus_expr): New function. (check_locus): New function. * gfortran.h: Add prototype for gfc_warning_internal.
Index: error.c =================================================================== --- error.c (Revision 242335) +++ error.c (Arbeitskopie) @@ -1160,7 +1160,25 @@ gfc_warning_now (int opt, const char *gmsgid, ...) return ret; } +/* Internal warning, do not buffer. */ +bool +gfc_warning_internal (int opt, const char *gmsgid, ...) +{ + va_list argp; + diagnostic_info diagnostic; + rich_location rich_loc (line_table, UNKNOWN_LOCATION); + bool ret; + + va_start (argp, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, + DK_NOTE); + diagnostic.option_index = opt; + ret = report_diagnostic (&diagnostic); + va_end (argp); + return ret; +} + /* Immediate error (i.e. do not buffer). */ void Index: frontend-passes.c =================================================================== --- frontend-passes.c (Revision 242335) +++ frontend-passes.c (Arbeitskopie) @@ -27,6 +27,14 @@ along with GCC; see the file COPYING3. If not see #include "constructor.h" #include "intrinsic.h" +/* Conditional compilations. */ + +#ifdef CHECKING_P +#define CHECK_LOCUS 1 +#else +#undef CHECK_LOCUS +#endif + /* Forward declarations. */ static void strip_function_call (gfc_expr *); @@ -48,6 +56,10 @@ static gfc_code * create_do_loop (gfc_expr *, gfc_ locus *, gfc_namespace *, char *vname=NULL); +#ifdef CHECK_LOCUS +static void check_locus (gfc_namespace *); +#endif + /* How deep we are inside an argument list. */ static int count_arglist; @@ -127,6 +139,10 @@ gfc_run_passes (gfc_namespace *ns) doloop_list.release (); int w, e; +#ifdef CHECK_LOCUS + check_locus (ns); +#endif + if (flag_frontend_optimize) { optimize_namespace (ns); @@ -145,6 +161,53 @@ gfc_run_passes (gfc_namespace *ns) realloc_strings (ns); } +#ifdef CHECK_LOCUS + +/* Callback function: Warn if there is no location information in a + statement. */ + +static int +check_locus_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + current_code = c; + if (c && *c && (((*c)->loc.nextc == NULL) || ((*c)->loc.lb == NULL))) + gfc_warning_internal (0, "No location in statement statement"); + + return 0; +} + +/* Callback function: Warn if there is no location information in an + expression. */ + +static int +check_locus_expr (gfc_expr **e, int *walk_subtrees ATTRIBUTE_UNUSED, + void *data ATTRIBUTE_UNUSED) +{ + + if (e && *e && (((*e)->where.nextc == NULL || (*e)->where.lb == NULL))) + gfc_warning_internal (0, "No location in expression near %L", + &((*current_code)->loc)); + return 0; + +} + +/* Run check for missing location information. */ + +static void +check_locus (gfc_namespace *ns) +{ + gfc_code_walker (&ns->code, check_locus_code, check_locus_expr, NULL); + + for (ns = ns->contained; ns; ns = ns->sibling) + { + if (ns->code == NULL || ns->code->op != EXEC_BLOCK) + check_locus (ns); + } +} + +#endif + /* Callback for each gfc_code node invoked from check_realloc_strings. For an allocatable LHS string which also appears as a variable on the RHS, replace Index: gfortran.h =================================================================== --- gfortran.h (Revision 242335) +++ gfortran.h (Arbeitskopie) @@ -2778,6 +2778,7 @@ const char *gfc_print_wide_char (gfc_char_t); bool gfc_warning (int opt, const char *, ...) ATTRIBUTE_GCC_GFC(2,3); bool gfc_warning_now (int opt, const char *, ...) ATTRIBUTE_GCC_GFC(2,3); +bool gfc_warning_internal (int opt, const char *, ...) ATTRIBUTE_GCC_GFC(2,3); bool gfc_warning_now_at (location_t loc, int opt, const char *gmsgid, ...) ATTRIBUTE_GCC_GFC(3,4);