Make sure we don't introduce a circularity into the variable set linked

list.  Fixes Savannah bug #15757.
This commit is contained in:
Paul Smith
2006-02-17 13:29:52 +00:00
parent 0806a403d6
commit bde826b18a
4 changed files with 53 additions and 7 deletions

View File

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

View 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

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

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