mirror of
https://github.com/mirror/make.git
synced 2024-12-30 23:10:52 +08:00
[SV 63047] Fix shuffle of SECONDEXPANSION prerequisites
Commit 07eea3aa4
`make --shuffle` prevented shuffling prerequisites
that use .SECONDEXPANSION, since shuffle happens before expansion.
This has two problems:
1. No shuffling happens for such prerequisites.
2. Use-after-free when outdated '->shuf' links are used.
Add a reshuffle into expansion phase right after dependency changes.
* src/file.c (expand_deps): Add reshuffle if dependencies change.
* src/shuffle.c (identity_shuffle_array): Fix comment typo.
* tests/scripts/options/shuffle: Add new SECONDEXPANSION test.
This commit is contained in:
parent
257b82ac1f
commit
ca4234c4b5
10
src/file.c
10
src/file.c
@ -25,6 +25,7 @@ this program. If not, see <http://www.gnu.org/licenses/>. */
|
|||||||
#include "variable.h"
|
#include "variable.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
#include "shuffle.h"
|
||||||
|
|
||||||
|
|
||||||
/* Remember whether snap_deps has been invoked: we need this to be sure we
|
/* Remember whether snap_deps has been invoked: we need this to be sure we
|
||||||
@ -576,6 +577,7 @@ expand_deps (struct file *f)
|
|||||||
struct dep **dp;
|
struct dep **dp;
|
||||||
const char *fstem;
|
const char *fstem;
|
||||||
int initialized = 0;
|
int initialized = 0;
|
||||||
|
int changed_dep = 0;
|
||||||
|
|
||||||
if (f->snapped)
|
if (f->snapped)
|
||||||
return;
|
return;
|
||||||
@ -664,6 +666,7 @@ expand_deps (struct file *f)
|
|||||||
if (new == 0)
|
if (new == 0)
|
||||||
{
|
{
|
||||||
*dp = d->next;
|
*dp = d->next;
|
||||||
|
changed_dep = 1;
|
||||||
free_dep (d);
|
free_dep (d);
|
||||||
d = *dp;
|
d = *dp;
|
||||||
continue;
|
continue;
|
||||||
@ -672,6 +675,7 @@ expand_deps (struct file *f)
|
|||||||
/* Add newly parsed prerequisites. */
|
/* Add newly parsed prerequisites. */
|
||||||
fstem = d->stem;
|
fstem = d->stem;
|
||||||
next = d->next;
|
next = d->next;
|
||||||
|
changed_dep = 1;
|
||||||
free_dep (d);
|
free_dep (d);
|
||||||
*dp = new;
|
*dp = new;
|
||||||
for (dp = &new, d = new; d != 0; dp = &d->next, d = d->next)
|
for (dp = &new, d = new; d != 0; dp = &d->next, d = d->next)
|
||||||
@ -688,6 +692,12 @@ expand_deps (struct file *f)
|
|||||||
*dp = next;
|
*dp = next;
|
||||||
d = *dp;
|
d = *dp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Shuffle mode assumes '->next' and '->shuf' links both traverse the same
|
||||||
|
dependencies (in different sequences). Regenerate '->shuf' so we don't
|
||||||
|
refer to stale data. */
|
||||||
|
if (changed_dep)
|
||||||
|
shuffle_deps_recursive (f->deps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add extra prereqs to the file in question. */
|
/* Add extra prereqs to the file in question. */
|
||||||
|
@ -146,7 +146,7 @@ identity_shuffle_array (void **a UNUSED, size_t len UNUSED)
|
|||||||
/* No-op! */
|
/* No-op! */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shuffle list of dependencies by populating '->next'
|
/* Shuffle list of dependencies by populating '->shuf'
|
||||||
field in each 'struct dep'. */
|
field in each 'struct dep'. */
|
||||||
static void
|
static void
|
||||||
shuffle_deps (struct dep *deps)
|
shuffle_deps (struct dep *deps)
|
||||||
|
@ -116,4 +116,13 @@ run_make_test('
|
|||||||
',
|
',
|
||||||
'--shuffle=reverse a_ b_ c_', "a_\nb_\nc_");
|
'--shuffle=reverse a_ b_ c_', "a_\nb_\nc_");
|
||||||
|
|
||||||
|
# Check if SECONDEXPANSION targets also get reshuffled.
|
||||||
|
run_make_test('
|
||||||
|
.SECONDEXPANSION:
|
||||||
|
all: $$(var)
|
||||||
|
%_: ; @echo $@
|
||||||
|
var = a_ b_ c_
|
||||||
|
',
|
||||||
|
'--shuffle=reverse', "c_\nb_\na_");
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
Loading…
Reference in New Issue
Block a user