diff mbox

[fortran,RFC] Add warning for missing location information

Message ID d36d037a-8a70-0022-71f1-ec626be5b691@netcologne.de
State New
Headers show

Commit Message

Thomas Koenig Nov. 14, 2016, 1:51 p.m. UTC
> the attached patch runs through gfortran's AST to check for missing
> location information.

... this time with attachment.

2016-11-14  Thomas Koenig  <tkoenig@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.

Comments

Janus Weil Nov. 22, 2016, 1:37 p.m. UTC | #1
Hi Thomas,

>> the attached patch runs through gfortran's AST to check for missing
>> location information.

one small comment: Is it necessary to introduce the extra CHECK_LOCUS
macro? Couldn't you just use CHECKING_P alone? In your patch
CHECK_LOCUS is basically just replicating CHECKING_P.

And: Why not use DK_WARNING instead of DK_NOTE?

Apart from that I don't see anything wrong with your patch (but I'm
probably not the best person to review it) ...

Cheers,
Janus



> 2016-11-14  Thomas Koenig  <tkoenig@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.
>
>
diff mbox

Patch

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);