* Removed a memory stomp (reading freed memory).
authorPaul Smith <psmith@gnu.org>
Fri, 3 Sep 1999 22:46:28 +0000 (22:46 +0000)
committerPaul Smith <psmith@gnu.org>
Fri, 3 Sep 1999 22:46:28 +0000 (22:46 +0000)
* Fixed some infinite recursion on rebuilt makefiles bugs.

ChangeLog
main.c
read.c
remake.c

index 3b80863540f71f0e7909cdb2fe092f5c43eb1e80..4e69369dd7e10cfd61be8ad6e67bb4b591e909c4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+1999-09-03  Paul D. Smith  <psmith@gnu.org>
+
+       * remake.c (notice_finished_file): Always set mtime_before_update
+       if it's not been set, not just if we ran some rules.  Otherwise we
+       may have a situation where a target's prerequisite was rebuilt but
+       not changed, so this target's rules weren't run, then
+       update_goal_chain() sees mtime_before_update != last_mtime and
+       thinks that the top-level target changed when it really didn't.
+       This can cause an infinite loop when remaking makefiles.
+       (update_goal_chain): If we get back to the top and we don't know
+       what the goal's last_mtime was, find it now.  We need to know so
+       we can compare it to mtime_before_update later (this is only
+       crucial when remaking makefiles--should we only do it then?)
+
+1999-09-02  Paul D. Smith  <psmith@gnu.org>
+
+       * read.c (read_makefile): If "override" appears as the first
+       prerequisite, look further to ensure this is really a
+       target-specific variable definition, and not just some
+       prerequisite named "override".
+
 1999-09-01  Paul D. Smith  <psmith@gnu.org>
 
        * function.c (IS_PATHSEP) [WINDOWS32]: Allow backslash separators
diff --git a/main.c b/main.c
index 86921bc142246f6faa8328c39169cb776080e668..802e889bbcd212c26b3f1c5a9781e760da072ef5 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1331,7 +1331,8 @@ int main (int argc, char ** argv)
        (ignore the jobserver pipe for this make) but print a message.  */
 
     if (job_slots > 0)
-      error (NILF, _("warning: -jN set for submakes: ignoring jobserver."));
+      error (NILF,
+             _("warning: -jN forced in submake: disabling jobserver mode."));
 
     /* Create a duplicate pipe, that will be closed in the SIGCHLD
        handler.  If this fails with EBADF, the parent has closed the pipe
@@ -1344,7 +1345,7 @@ int main (int argc, char ** argv)
           pfatal_with_name (_("dup jobserver"));
 
         error (NILF,
-               _("warning: jobserver unavailable (using -j1).  Add `+' to parent make rule."));
+               _("warning: jobserver unavailable: using -j1.  Add `+' to parent make rule."));
         job_slots = 1;
       }
 
diff --git a/read.c b/read.c
index bf2be05913284536b77f761d28f8a272b0adb6dc..ed9a2b09aca2dce658ad28f32e5f5f94fa28a16c 100644 (file)
--- a/read.c
+++ b/read.c
@@ -177,10 +177,12 @@ read_all_makefiles (makefiles)
 
     while ((name = find_next_token (&p, &length)) != 0)
       {
+        name = xstrdup (name);
        if (*p != '\0')
          *p++ = '\0';
-       (void) read_makefile (name,
-                             RM_NO_DEFAULT_GOAL | RM_INCLUDED | RM_DONTCARE);
+       if (read_makefile (name,
+                           RM_NO_DEFAULT_GOAL|RM_INCLUDED|RM_DONTCARE) < 2)
+          free (name);
       }
 
     free (value);
@@ -269,7 +271,9 @@ read_all_makefiles (makefiles)
 
    FILENAME is added to the `read_makefiles' chain.
 
-   Returns 1 if a file was found and read, 0 if not.  */
+   Returns 0 if a file was not found or not read.
+   Returns 1 if FILENAME was found and read.
+   Returns 2 if FILENAME was read, and we kept a reference (don't free it).  */
 
 static int
 read_makefile (filename, flags)
@@ -289,6 +293,7 @@ read_makefile (filename, flags)
   int len, reading_target;
   int ignoring = 0, in_ignored_define = 0;
   int no_targets = 0;          /* Set when reading a rule without targets.  */
+  int using_filename = 0;
   struct floc fileinfo;
   char *passed_filename = filename;
 
@@ -307,10 +312,12 @@ read_makefile (filename, flags)
   do                                                                         \
     {                                                                        \
       if (filenames != 0)                                                    \
-       record_files (filenames, pattern, pattern_percent, deps,              \
-                     cmds_started, commands, commands_idx,                   \
-                     two_colon, &fileinfo,                                   \
-                     !(flags & RM_NO_DEFAULT_GOAL));                         \
+        {                                                                     \
+         record_files (filenames, pattern, pattern_percent, deps,            \
+                        cmds_started, commands, commands_idx, two_colon,      \
+                        &fileinfo, !(flags & RM_NO_DEFAULT_GOAL));           \
+          using_filename |= commands_idx > 0;                                 \
+        }                                                                     \
       filenames = 0;                                                         \
       commands_idx = 0;                                                              \
       if (pattern) { free(pattern); pattern = 0; }                            \
@@ -685,16 +692,18 @@ read_makefile (filename, flags)
            {
              struct nameseq *next = files->next;
              char *name = files->name;
+              int r;
+
              free ((char *)files);
              files = next;
 
-             if (! read_makefile (name, (RM_INCLUDED | RM_NO_TILDE
-                                         | (noerror ? RM_DONTCARE : 0)))
-                 && ! noerror)
+              r = read_makefile (name, (RM_INCLUDED | RM_NO_TILDE
+                                        | (noerror ? RM_DONTCARE : 0)));
+             if (!r && !noerror)
                error (&fileinfo, "%s: %s", name, strerror (errno));
 
-              /* We can't free NAME here, in case some of the commands,
-                 etc. still contain references to the filename.  */
+              if (r < 2)
+                free (name);
            }
 
          /* Free any space allocated by conditional_line.  */
@@ -880,7 +889,7 @@ read_makefile (filename, flags)
               continue;
             }
           /* This should never be possible; we handled it above.  */
-         assert(*p2 != '\0');
+         assert (*p2 != '\0');
           ++p2;
 
          /* Is this a one-colon or two-colon entry?  */
@@ -895,25 +904,31 @@ read_makefile (filename, flags)
           if (*lb_next != '\0')
             {
               unsigned int l = p2 - variable_buffer;
-              plen = strlen(p2);
-              (void)variable_buffer_output(p2+plen,
-                                           lb_next, strlen(lb_next)+1);
+              plen = strlen (p2);
+              (void) variable_buffer_output (p2+plen,
+                                             lb_next, strlen (lb_next)+1);
               p2 = variable_buffer + l;
             }
-          wtype = get_next_mword(p2, NULL, &p, &len);
+
+          /* See if it's an "override" keyword; if so see if what comes after
+             it looks like a variable definition.  */
+
+          wtype = get_next_mword (p2, NULL, &p, &len);
+
           v_origin = o_file;
-          if (wtype == w_static && (len == (sizeof("override")-1)
-                                    && strneq(p, "override", len)))
+          if (wtype == w_static && (len == (sizeof ("override")-1)
+                                    && strneq (p, "override", len)))
             {
               v_origin = o_override;
-              (void)get_next_mword(p+len, NULL, &p, &len);
+              wtype = get_next_mword (p+len, NULL, &p, &len);
             }
-          else if (wtype != w_eol)
-            wtype = get_next_mword(p+len, NULL, NULL, NULL);
 
-          if (wtype == w_varassign || v_origin == o_override)
+          if (wtype != w_eol)
+            wtype = get_next_mword (p+len, NULL, NULL, NULL);
+
+          if (wtype == w_varassign)
             {
-              record_target_var(filenames, p, two_colon, v_origin, &fileinfo);
+              record_target_var (filenames, p, two_colon, v_origin, &fileinfo);
               filenames = 0;
               continue;
             }
@@ -929,7 +944,7 @@ read_makefile (filename, flags)
           if (*lb_next != '\0')
             {
               unsigned int l = p2 - variable_buffer;
-              (void)variable_expand_string(p2 + plen, lb_next, (long)-1);
+              (void) variable_expand_string (p2 + plen, lb_next, (long)-1);
               p2 = variable_buffer + l;
 
               /* Look for a semicolon in the expanded line.  */
@@ -1046,7 +1061,7 @@ read_makefile (filename, flags)
 
   reading_file = 0;
 
-  return 1;
+  return 1+using_filename;
 }
 \f
 /* Execute a `define' directive.
index 38d643b1504c3a68416dfb1d4c9b85ac23cb0616..1e21e618e71a51dcca66a299a8a35b02c670c331 100644 (file)
--- a/remake.c
+++ b/remake.c
@@ -1,5 +1,5 @@
 /* Basic dependency engine for GNU Make.
-Copyright (C) 1988,89,90,91,92,93,94,95,96,97 Free Software Foundation, Inc.
+Copyright (C) 1988,89,90,91,92,93,94,95,96,97,99 Free Software Foundation, Inc.
 This file is part of GNU Make.
 
 GNU Make is free software; you can redistribute it and/or modify
@@ -154,6 +154,13 @@ update_goal_chain (goals, makefiles)
              x = update_file (file, makefiles ? 1 : 0);
              check_renamed (file);
 
+              /* If we don't know what the file's last mtime was, find it.  */
+              if (! file->last_mtime)
+                {
+                  (void) f_mtime (file, 0);
+                  check_renamed (file);
+                }
+
              /* Set the goal's `changed' flag if any commands were started
                 by calling update_file above.  We check this flag below to
                 decide when to give an "up to date" diagnostic.  */
@@ -553,7 +560,8 @@ update_file_1 (file, depth)
 
       if (depth == 0 && keep_going_flag
          && !just_print_flag && !question_flag)
-       error (NILF, _("Target `%s' not remade because of errors."), file->name);
+       error (NILF,
+               _("Target `%s' not remade because of errors."), file->name);
 
       return dep_status;
     }
@@ -736,13 +744,13 @@ notice_finished_file (file)
        }
     }
 
+  if (file->mtime_before_update == 0)
+    file->mtime_before_update = file->last_mtime;
+
   if (ran && !file->phony)
     {
       struct file *f;
 
-      assert(file->mtime_before_update == 0);
-      file->mtime_before_update = file->last_mtime;
-
       if (just_print_flag || question_flag
          || (file->is_target && file->cmds == 0))
        file->last_mtime = NEW_MTIME;