From 6970561de07e071b85f0681062756f316eead29b Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Sun, 4 Aug 2024 17:13:07 -0400 Subject: [PATCH] Don't add a target to its own also_make list * src/dep.h (copy_dep): Make a copy of one struct dep. * src/misc.c (copy_dep): Implement the new function. (copy_dep_chain): Call copy_dep() for each dep in the chain. * src/read.c (record_files): Write our own copy loop and omit the current file from its own also_make list. Since we don't keep the function's also_make, free it. --- src/dep.h | 2 +- src/misc.c | 33 ++++++++++++++++++++++++--------- src/read.c | 19 +++++++++++++------ 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/src/dep.h b/src/dep.h index 5b60521f..abdfaf45 100644 --- a/src/dep.h +++ b/src/dep.h @@ -42,7 +42,6 @@ struct nameseq explicit is set when implicit rule search is performed and the prerequisite does not contain %. When explicit is set the file is not intermediate. */ - #define DEP(_t) \ NAMESEQ (_t); \ struct file *file; \ @@ -132,6 +131,7 @@ SI void free_goal_chain (struct goaldep *g) { free_dep_chain((struct dep *)g); } # define free_goal_chain(_g) free_ns_chain ((struct nameseq *)(_g)) #endif +struct dep *copy_dep (const struct dep *d); struct dep *copy_dep_chain (const struct dep *d); struct goaldep *read_all_makefiles (const char **makefiles); diff --git a/src/misc.c b/src/misc.c index a53301df..1914aa22 100644 --- a/src/misc.c +++ b/src/misc.c @@ -528,23 +528,38 @@ readbuf (int fd, void *buffer, size_t len) } +/* Copy a 'struct dep'. For 2nd expansion deps, dup the name. */ + +struct dep * +copy_dep (const struct dep *d) +{ + struct dep *new = NULL; + + if (d) + { + new = xmalloc (sizeof (struct dep)); + memcpy (new, d, sizeof (struct dep)); + + if (new->need_2nd_expansion) + new->name = xstrdup (new->name); + new->next = 0; + } + + return new; +} + /* Copy a chain of 'struct dep'. For 2nd expansion deps, dup the name. */ struct dep * copy_dep_chain (const struct dep *d) { - struct dep *firstnew = 0; - struct dep *lastnew = 0; + struct dep *firstnew = NULL; + struct dep *lastnew = NULL; while (d != 0) { - struct dep *c = xmalloc (sizeof (struct dep)); - memcpy (c, d, sizeof (struct dep)); + struct dep *c = copy_dep (d); - if (c->need_2nd_expansion) - c->name = xstrdup (c->name); - - c->next = 0; if (firstnew == 0) firstnew = lastnew = c; else @@ -562,7 +577,7 @@ copy_dep_chain (const struct dep *d) void free_ns_chain (struct nameseq *ns) { - while (ns != 0) + while (ns != NULL) { struct nameseq *t = ns; ns = ns->next; diff --git a/src/read.c b/src/read.c index 0fb783a2..8a487a94 100644 --- a/src/read.c +++ b/src/read.c @@ -2110,7 +2110,6 @@ record_files (struct nameseq *filenames, int are_also_makes, return; } - /* Walk through each target and create it in the database. We already set up the first target, above. */ while (1) @@ -2283,15 +2282,14 @@ record_files (struct nameseq *filenames, int are_also_makes, } /* If there are also-makes, then populate a copy of the also-make list into - each one. For the last file, we take our original also_make list instead - wastefully copying it one more time and freeing it. */ + each one. Omit the file from its also-make list. */ { struct dep *i; for (i = also_make; i != NULL; i = i->next) { struct file *f = i->file; - struct dep *cpy = i->next ? copy_dep_chain (also_make) : also_make; + struct dep *dp; if (f->also_make) { @@ -2299,11 +2297,20 @@ record_files (struct nameseq *filenames, int are_also_makes, _("warning: overriding group membership for target '%s'"), f->name); free_dep_chain (f->also_make); + f->also_make = NULL; } - f->also_make = cpy; + for (dp = also_make; dp != NULL; dp = dp->next) + if (dp->file != f) + { + struct dep *cpy = copy_dep (dp); + cpy->next = f->also_make; + f->also_make = cpy; + } } - } + + free_dep_chain (also_make); + } } /* Search STRING for an unquoted STOPMAP.