]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 63047] Fix shuffle of SECONDEXPANSION prerequisites
authorSergei Trofimovich <siarheit@google.com>
Sun, 11 Sep 2022 20:28:59 +0000 (21:28 +0100)
committerPaul Smith <psmith@gnu.org>
Mon, 12 Sep 2022 05:05:31 +0000 (01:05 -0400)
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.

src/file.c
src/shuffle.c
tests/scripts/options/shuffle

index 7596ff103759897645e0cf17d278cb95473500e5..2cb013ef0f3d38ec46f59872d632af2e13ef5ec4 100644 (file)
@@ -25,6 +25,7 @@ this program.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "variable.h"
 #include "debug.h"
 #include "hash.h"
+#include "shuffle.h"
 
 
 /* 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;
   const char *fstem;
   int initialized = 0;
+  int changed_dep = 0;
 
   if (f->snapped)
     return;
@@ -664,6 +666,7 @@ expand_deps (struct file *f)
       if (new == 0)
         {
           *dp = d->next;
+          changed_dep = 1;
           free_dep (d);
           d = *dp;
           continue;
@@ -672,6 +675,7 @@ expand_deps (struct file *f)
       /* Add newly parsed prerequisites.  */
       fstem = d->stem;
       next = d->next;
+      changed_dep = 1;
       free_dep (d);
       *dp = new;
       for (dp = &new, d = new; d != 0; dp = &d->next, d = d->next)
@@ -688,6 +692,12 @@ expand_deps (struct file *f)
       *dp = next;
       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.  */
index d78bfd8fc5892cc77a3b4faf4f04f0e24df2104d..ca54e528ad5601fabcbb49352d4e150b608a0d83 100644 (file)
@@ -146,7 +146,7 @@ identity_shuffle_array (void **a UNUSED, size_t len UNUSED)
   /* No-op!  */
 }
 
-/* Shuffle list of dependencies by populating '->next'
+/* Shuffle list of dependencies by populating '->shuf'
    field in each 'struct dep'.  */
 static void
 shuffle_deps (struct dep *deps)
index e037ed1a86f850062653d7a4ee7d3dc2e926d9cd..5661683c0ab1088fb94685e914bfff16c1bfed61 100644 (file)
@@ -116,4 +116,13 @@ run_make_test('
 ',
               '--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;