From bde826b18aeb6fd3c9de7a7733d1e163efde90e1 Mon Sep 17 00:00:00 2001 From: Paul Smith Date: Fri, 17 Feb 2006 13:29:52 +0000 Subject: Make sure we don't introduce a circularity into the variable set linked list. Fixes Savannah bug #15757. --- ChangeLog | 9 +++++++++ tests/ChangeLog | 6 ++++++ tests/scripts/features/targetvars | 25 +++++++++++++++++++++++++ variable.c | 20 +++++++++++++------- 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 + + * 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 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 + + * 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 * 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; -- cgit v1.2.3