Make sure we don't introduce a circularity into the variable set linked
authorPaul Smith <psmith@gnu.org>
Fri, 17 Feb 2006 13:29:52 +0000 (13:29 +0000)
committerPaul Smith <psmith@gnu.org>
Fri, 17 Feb 2006 13:29:52 +0000 (13:29 +0000)
list.  Fixes Savannah bug #15757.

ChangeLog
tests/ChangeLog
tests/scripts/features/targetvars
variable.c

index e86bc3e6ed36351b8018b35d45f3dce6b9d61105..07d1e52f82f85f722c954c2a977d67d9dbb36eba 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2006-02-17  Paul D. Smith  <psmith@gnu.org>
+
+       * variable.c (merge_variable_set_lists): Don't try to merge the
+       global_setlist.  Not only is this useless, but it can lead to
+       circularities in the linked list, if global_setlist->next in one
+       list gets set to point to another list which also ends in
+       global_setlist.
+       Fixes Savannah bug #15757.
+
 2006-02-15  Paul D. Smith  <psmith@gnu.org>
 
        Fix for Savannah bug #106.
index c1342cb0438a2b214ae5d8518551ac24474efbd9..57dec0d0908f94daf9af9199e062e69e8507e5f3 100644 (file)
@@ -1,3 +1,9 @@
+2006-02-17  Paul D. Smith  <psmith@gnu.org>
+
+       * scripts/features/targetvars: Test a complex construction which
+       guarantees that we have to merge variable lists of different
+       sizes.  Tests for Savannah bug #15757.
+
 2006-02-15  Paul D. Smith  <psmith@gnu.org>
 
        * scripts/functions/error: Make sure filename/lineno information
index 3989340c1c30cff40f719dbab78c6d0ab32cc6ea..c22ce135a541c8fd4b819a0247e2b8e9ed80caa0 100644 (file)
@@ -267,4 +267,29 @@ close(MAKEFILE);
 $answer = "no build information\n";
 &compare_output($answer, &get_logfile(1));
 
+# TEST #17
+
+# Test a merge of set_lists for files, where one list is much longer
+# than the other.  See Savannah bug #15757.
+
+mkdir('t1');
+touch('t1/rules.mk');
+
+run_make_test('
+VPATH = t1
+include rules.mk
+.PHONY: all
+all: foo.x
+foo.x : rules.mk ; @echo MYVAR=$(MYVAR) FOOVAR=$(FOOVAR) ALLVAR=$(ALLVAR)
+all: ALLVAR = xxx
+foo.x: FOOVAR = bar
+rules.mk : MYVAR = foo
+.INTERMEDIATE: foo.x rules.mk
+',
+              '-I t1',
+              'MYVAR= FOOVAR=bar ALLVAR=xxx');
+
+rmfiles('t1/rules.mk');
+rmdir('t1');
+
 1;
index 0ea71cdbf34f4f49ece9ff697ea1b0d3ebd0df56..39f0adaa2bd6b52adbad898ab392f8a8d1207ad4 100644 (file)
@@ -665,21 +665,27 @@ void
 merge_variable_set_lists (struct variable_set_list **setlist0,
                           struct variable_set_list *setlist1)
 {
-  register struct variable_set_list *list0 = *setlist0;
+  struct variable_set_list *to = *setlist0;
   struct variable_set_list *last0 = 0;
 
-  while (setlist1 != 0 && list0 != 0)
+  /* If there's nothing to merge, stop now.  */
+  if (!setlist1)
+    return;
+
+  /* This loop relies on the fact that all setlists terminate with the global
+     setlist (before NULL).  If that's not true, arguably we SHOULD die.  */
+  while (setlist1 != &global_setlist && to != &global_setlist)
     {
-      struct variable_set_list *next = setlist1;
+      struct variable_set_list *from = setlist1;
       setlist1 = setlist1->next;
 
-      merge_variable_sets (list0->set, next->set);
+      merge_variable_sets (to->set, from->set);
 
-      last0 = list0;
-      list0 = list0->next;
+      last0 = to;
+      to = to->next;
     }
 
-  if (setlist1 != 0)
+  if (setlist1 != &global_setlist)
     {
       if (last0 == 0)
        *setlist0 = setlist1;