This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Don't ICE on invalid preprocessor lines


Hi!

gfortran ICEs when it encounters a bogus preprocessor line.
This patches cures the ICE and emits a warning, similarly to what
the C compiler emits in such cases.  Ok for HEAD and 4.0.2, once it
reopens?

2005-07-07  Jakub Jelinek  <jakub@redhat.com>

	* scanner.c (preprocessor_line): Only set current_file->line when errors
	have not been encountered.  Warn and don't crash if a file leave
	preprocessor line has no corresponding entering line.  Formatting.

--- gcc/fortran/scanner.c.jj	2005-07-07 14:18:15.000000000 +0200
+++ gcc/fortran/scanner.c	2005-07-07 14:30:10.000000000 +0200
@@ -839,15 +839,13 @@ preprocessor_line (char *c)
 
   line = atoi (c);
 
-  /* Set new line number.  */
-  current_file->line = line;
-
-  c = strchr (c, ' '); 
+  c = strchr (c, ' ');
   if (c == NULL)
-    /* No file name given.  */
-    return;
-
-
+    {
+      /* No file name given.  Set new line number.  */
+      current_file->line = line;
+      return;
+    }
 
   /* Skip spaces.  */
   while (*c == ' ' || *c == '\t')
@@ -880,7 +878,7 @@ preprocessor_line (char *c)
 
 
   /* Get flags.  */
-  
+
   flag[1] = flag[2] = flag[3] = flag[4] = flag[5] = false;
 
   for (;;)
@@ -895,24 +893,32 @@ preprocessor_line (char *c)
       if (1 <= i && i <= 4)
 	flag[i] = true;
     }
-     
+
   /* Interpret flags.  */
-  
+
   if (flag[1] || flag[3]) /* Starting new file.  */
     {
       f = get_file (filename, LC_RENAME);
       f->up = current_file;
       current_file = f;
     }
-  
+
   if (flag[2]) /* Ending current file.  */
     {
-      current_file = current_file->up;
+      if (strcmp (current_file->filename, filename) != 0)
+	{
+	  gfc_warning_now ("%s:%d: file %s left but not entered",
+			   current_file->filename, current_file->line,
+			   filename);
+	  return;
+	}
+      if (current_file->up)
+	current_file = current_file->up;
     }
-  
+
   /* The name of the file can be a temporary file produced by
      cpp. Replace the name if it is different.  */
-  
+
   if (strcmp (current_file->filename, filename) != 0)
     {
       gfc_free (current_file->filename);
@@ -920,10 +926,12 @@ preprocessor_line (char *c)
       strcpy (current_file->filename, filename);
     }
 
+  /* Set new line number.  */
+  current_file->line = line;
   return;
 
  bad_cpp_line:
-  gfc_warning_now ("%s:%d: Illegal preprocessor directive", 
+  gfc_warning_now ("%s:%d: Illegal preprocessor directive",
 		   current_file->filename, current_file->line);
   current_file->line++;
 }
--- gcc/testsuite/gfortran.dg/badline.f.jj	2005-07-07 14:22:36.000000000 +0200
+++ gcc/testsuite/gfortran.dg/badline.f	2005-07-07 14:31:38.000000000 +0200
@@ -0,0 +1,4 @@
+	subroutine foo 
+# 18 "src/badline.F" 2
+	end
+! { dg-warning "left but not entered" "" { target *-*-* } 2 }

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]