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.
This commit is contained in:
Paul Smith 2024-08-04 17:13:07 -04:00
parent f0db5e321f
commit 6970561de0
3 changed files with 38 additions and 16 deletions

View file

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

View file

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

View file

@ -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.