Module Name:    src
Committed By:   rillig
Date:           Mon Nov 23 14:47:12 UTC 2020

Modified Files:
        src/usr.bin/make: suff.c
        src/usr.bin/make/unit-tests: suff-transform-endless.exp
            suff-transform-endless.mk suff-transform-select.exp
            suff-transform-select.mk

Log Message:
make(1): fix endless loop when resolving circular suffix rules


To generate a diff of this commit:
cvs rdiff -u -r1.305 -r1.306 src/usr.bin/make/suff.c
cvs rdiff -u -r1.2 -r1.3 \
    src/usr.bin/make/unit-tests/suff-transform-endless.exp \
    src/usr.bin/make/unit-tests/suff-transform-select.exp \
    src/usr.bin/make/unit-tests/suff-transform-select.mk
cvs rdiff -u -r1.3 -r1.4 \
    src/usr.bin/make/unit-tests/suff-transform-endless.mk

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/make/suff.c
diff -u src/usr.bin/make/suff.c:1.305 src/usr.bin/make/suff.c:1.306
--- src/usr.bin/make/suff.c:1.305	Mon Nov 23 14:04:28 2020
+++ src/usr.bin/make/suff.c	Mon Nov 23 14:47:12 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: suff.c,v 1.305 2020/11/23 14:04:28 rillig Exp $	*/
+/*	$NetBSD: suff.c,v 1.306 2020/11/23 14:47:12 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -114,7 +114,7 @@
 #include "dir.h"
 
 /*	"@(#)suff.c	8.4 (Berkeley) 3/21/94"	*/
-MAKE_RCSID("$NetBSD: suff.c,v 1.305 2020/11/23 14:04:28 rillig Exp $");
+MAKE_RCSID("$NetBSD: suff.c,v 1.306 2020/11/23 14:47:12 rillig Exp $");
 
 #define SUFF_DEBUG0(text) DEBUG0(SUFF, text)
 #define SUFF_DEBUG1(fmt, arg1) DEBUG1(SUFF, fmt, arg1)
@@ -1060,6 +1060,9 @@ RemoveCandidate(CandidateList *srcs)
 static Candidate *
 FindThem(CandidateList *srcs, CandidateSearcher *cs)
 {
+    HashTable seen;
+
+    HashTable_Init(&seen);
 
     while (!Lst_IsEmpty(srcs)) {
 	Candidate *src = Lst_Dequeue(srcs);
@@ -1074,6 +1077,8 @@ FindThem(CandidateList *srcs, CandidateS
 	 * graph for it or the file actually exists.
 	 */
 	if (Targ_FindNode(src->file) != NULL) {
+	found:
+	    HashTable_Done(&seen);
 	    SUFF_DEBUG0("got it\n");
 	    return src;
 	}
@@ -1082,17 +1087,28 @@ FindThem(CandidateList *srcs, CandidateS
 	    char *file = Dir_FindFile(src->file, src->suff->searchPath);
 	    if (file != NULL) {
 		free(file);
-		SUFF_DEBUG0("got it\n");
-		return src;
+		goto found;
 	    }
 	}
 
 	SUFF_DEBUG0("not there\n");
 
-	CandidateList_AddCandidatesFor(srcs, src);
+	{
+	    Boolean isNew;
+
+	    HashTable_CreateEntry(&seen, src->file, &isNew);
+	    if (isNew)
+		CandidateList_AddCandidatesFor(srcs, src);
+	    else {
+		DEBUG1(SUFF, "FindThem: skipping duplicate \"%s\"\n",
+		       src->file);
+	    }
+	}
+
 	CandidateSearcher_Add(cs, src);
     }
 
+    HashTable_Done(&seen);
     return NULL;
 }
 

Index: src/usr.bin/make/unit-tests/suff-transform-endless.exp
diff -u src/usr.bin/make/unit-tests/suff-transform-endless.exp:1.2 src/usr.bin/make/unit-tests/suff-transform-endless.exp:1.3
--- src/usr.bin/make/unit-tests/suff-transform-endless.exp:1.2	Mon Nov 23 14:13:39 2020
+++ src/usr.bin/make/unit-tests/suff-transform-endless.exp	Mon Nov 23 14:47:12 2020
@@ -17,7 +17,27 @@ inserting ".f" (4) at end of list
 defining transformation from `.f' to `.e'
 inserting ".f" (4) at end of list
 inserting ".e" (3) at end of list
-make: "suff-transform-endless.mk" line 38: prevent endless loop
-
-make: stopped in unit-tests
-exit status 1
+transformation .e complete
+transformation .e.f complete
+transformation .f.e complete
+Wildcard expanding "all"...
+SuffFindDeps "all"
+	No known suffix on all. Using .NULL suffix
+adding suffix rules
+	trying all.e...not there
+	trying all.d...not there
+	trying all.f...not there
+	trying all.c...not there
+	trying all.e...not there
+FindThem: skipping duplicate "all.e"
+Wildcard expanding "issue6.f"...suffix is ".f"...
+SuffFindDeps "issue6.f"
+	trying issue6.e...not there
+	trying issue6.d...not there
+	trying issue6.f...got it
+	applying .f -> .e to "issue6.e"
+	applying .e -> .f to "issue6.f"
+suffix is ".e"...
+make: Graph cycles through issue6.f
+`all' not remade because of errors.
+exit status 0
Index: src/usr.bin/make/unit-tests/suff-transform-select.exp
diff -u src/usr.bin/make/unit-tests/suff-transform-select.exp:1.2 src/usr.bin/make/unit-tests/suff-transform-select.exp:1.3
--- src/usr.bin/make/unit-tests/suff-transform-select.exp:1.2	Mon Nov 23 14:13:39 2020
+++ src/usr.bin/make/unit-tests/suff-transform-select.exp	Mon Nov 23 14:47:12 2020
@@ -21,7 +21,24 @@ inserting ".e" (3) at end of list
 transformation .e complete
 transformation .e.f complete
 transformation .f.e complete
-make: "suff-transform-select.mk" line 30: prevent endless loop
-
-make: stopped in unit-tests
-exit status 1
+Wildcard expanding "all"...
+SuffFindDeps "all"
+	No known suffix on all. Using .NULL suffix
+adding suffix rules
+	trying all.e...not there
+	trying all.d...not there
+	trying all.f...not there
+	trying all.c...not there
+	trying all.e...not there
+FindThem: skipping duplicate "all.e"
+Wildcard expanding "issue10.e"...suffix is ".e"...
+SuffFindDeps "issue10.e"
+	trying issue10.d...got it
+suffix is ".d"...
+SuffFindDeps "issue10.d"
+	trying issue10.c...not there
+suffix is ".d"...
+: 'Making issue10.d out of nothing.'
+make: don't know how to make issue10.e (continuing)
+`all' not remade because of errors.
+exit status 0
Index: src/usr.bin/make/unit-tests/suff-transform-select.mk
diff -u src/usr.bin/make/unit-tests/suff-transform-select.mk:1.2 src/usr.bin/make/unit-tests/suff-transform-select.mk:1.3
--- src/usr.bin/make/unit-tests/suff-transform-select.mk:1.2	Mon Nov 23 14:13:39 2020
+++ src/usr.bin/make/unit-tests/suff-transform-select.mk	Mon Nov 23 14:47:12 2020
@@ -1,4 +1,4 @@
-# $NetBSD: suff-transform-select.mk,v 1.2 2020/11/23 14:13:39 rillig Exp $
+# $NetBSD: suff-transform-select.mk,v 1.3 2020/11/23 14:47:12 rillig Exp $
 #
 # https://gnats.netbsd.org/49086, issue 10:
 # Explicit dependencies affect transformation rule selection.
@@ -27,4 +27,5 @@ issue10.d issue10.f:
 
 # XXX: see suff-bug-endless, which must be fixed first.
 #.MAKEFLAGS: -dg1
-.error prevent endless loop
+
+# Before 24-11-2020, resolving all.e ran into an endless loop.

Index: src/usr.bin/make/unit-tests/suff-transform-endless.mk
diff -u src/usr.bin/make/unit-tests/suff-transform-endless.mk:1.3 src/usr.bin/make/unit-tests/suff-transform-endless.mk:1.4
--- src/usr.bin/make/unit-tests/suff-transform-endless.mk:1.3	Mon Nov 23 14:13:39 2020
+++ src/usr.bin/make/unit-tests/suff-transform-endless.mk	Mon Nov 23 14:47:12 2020
@@ -1,4 +1,4 @@
-# $NetBSD: suff-transform-endless.mk,v 1.3 2020/11/23 14:13:39 rillig Exp $
+# $NetBSD: suff-transform-endless.mk,v 1.4 2020/11/23 14:47:12 rillig Exp $
 
 # https://gnats.netbsd.org/49086, issue 6:
 # Transformation search can end up in an infinite loop.
@@ -35,4 +35,5 @@ all: issue6.f
 # XXX: Found 'all' as '(not found)'
 # XXX: trying all.e, all.e, all.f, all.e, all.e, repeatedly.
 #.MAKEFLAGS: -dg1
-.error prevent endless loop
+
+# Before 24-11-2020, resolving all.e ran into an endless loop.

Reply via email to