summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Smith <psmith@gnu.org>2006-02-17 13:29:52 +0000
committerPaul Smith <psmith@gnu.org>2006-02-17 13:29:52 +0000
commitbde826b18aeb6fd3c9de7a7733d1e163efde90e1 (patch)
tree8de85f137b768170247e18a2a2c95652a637530d
parent0806a403d65ef6a7f16e2c17aa8286100ebad5d7 (diff)
downloadgunmake-bde826b18aeb6fd3c9de7a7733d1e163efde90e1.tar.gz
Make sure we don't introduce a circularity into the variable set linked
list. Fixes Savannah bug #15757.
-rw-r--r--ChangeLog9
-rw-r--r--tests/ChangeLog6
-rw-r--r--tests/scripts/features/targetvars25
-rw-r--r--variable.c20
4 files changed, 53 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index e86bc3e..07d1e52 100644
--- 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.
diff --git a/tests/ChangeLog b/tests/ChangeLog
index c1342cb..57dec0d 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -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
diff --git a/tests/scripts/features/targetvars b/tests/scripts/features/targetvars
index 3989340..c22ce13 100644
--- a/tests/scripts/features/targetvars
+++ b/tests/scripts/features/targetvars
@@ -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;
diff --git a/variable.c b/variable.c
index 0ea71cd..39f0ada 100644
--- a/variable.c
+++ b/variable.c
@@ -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;