diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 280c35e43312767ba3893142d02087454f73e30e..170c6fbdeff3d7a84cf47a9ddee19714e81979ee 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,15 @@
+2011-11-29  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+	PR fortran/40958
+	* module.c (prev_module_line):  New variable.
+	(prev_module_column):  New variable.
+	(prev_character):  New variable.
+	(module_char):  Update the new variables.
+	(module_unget_char):  New function.
+	(parse_string):  Use module_unget_char.
+	(parse_integer):  Likewise.
+	(parse_name):  Likewise.
+
 2011-11-29  Tobias Burnus  <burnus@net-b.de>
 
 	PR fortran/51306
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 7c28e8bb97cc96222d6451d2f7fe38f523b5d869..70f8565c1507a55f7118acfc2418d1a3bef3d3bd 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -194,6 +194,8 @@ static char module_name[GFC_MAX_SYMBOL_LEN + 1];
 static bool specified_nonint, specified_int;
 
 static int module_line, module_column, only_flag;
+static int prev_module_line, prev_module_column, prev_character;
+
 static enum
 { IO_INPUT, IO_OUTPUT }
 iomode;
@@ -1036,6 +1038,10 @@ module_char (void)
   if (c == EOF)
     bad_module ("Unexpected EOF");
 
+  prev_module_line = module_line;
+  prev_module_column = module_column;
+  prev_character = c;
+
   if (c == '\n')
     {
       module_line++;
@@ -1046,6 +1052,16 @@ module_char (void)
   return c;
 }
 
+/* Unget a character while remembering the line and column.  Works for
+   a single character only.  */
+
+static void
+module_unget_char (void)
+{
+  module_line = prev_module_line;
+  module_column = prev_module_column;
+  ungetc (prev_character, module_fp);
+}
 
 /* Parse a string constant.  The delimiter is guaranteed to be a
    single quote.  */
@@ -1106,24 +1122,22 @@ parse_string (void)
 static void
 parse_integer (int c)
 {
-  module_locus m;
-
   atom_int = c - '0';
 
   for (;;)
     {
-      get_module_locus (&m);
-
       c = module_char ();
       if (!ISDIGIT (c))
-	break;
+	{
+	  module_unget_char ();
+	  break;
+	}
 
       atom_int = 10 * atom_int + c - '0';
       if (atom_int > 99999999)
 	bad_module ("Integer overflow");
     }
 
-  set_module_locus (&m);
 }
 
 
@@ -1132,7 +1146,6 @@ parse_integer (int c)
 static void
 parse_name (int c)
 {
-  module_locus m;
   char *p;
   int len;
 
@@ -1141,13 +1154,14 @@ parse_name (int c)
   *p++ = c;
   len = 1;
 
-  get_module_locus (&m);
-
   for (;;)
     {
       c = module_char ();
       if (!ISALNUM (c) && c != '_' && c != '-')
-	break;
+	{
+	  module_unget_char ();
+	  break;
+	}
 
       *p++ = c;
       if (++len > GFC_MAX_SYMBOL_LEN)
@@ -1156,11 +1170,6 @@ parse_name (int c)
 
   *p = '\0';
 
-  fseek (module_fp, -1, SEEK_CUR);
-  module_column = m.column + len - 1;
-
-  if (c == '\n')
-    module_line--;
 }