Mon Jun 15 14:46:28 2020 UTC ()
make(1): fix performance problem in specially crafted :M modifier

This fix was previously suspected to make the vax build fail.  The next
build succeeded though, and it started 2 hours before this fix was
reverted.


(rillig)
diff -r1.47 -r1.48 src/usr.bin/make/str.c
diff -r1.5 -r1.6 src/usr.bin/make/unit-tests/modmatch.mk

cvs diff -r1.47 -r1.48 src/usr.bin/make/str.c (expand / switch to unified diff)

--- src/usr.bin/make/str.c 2020/06/14 23:13:21 1.47
+++ src/usr.bin/make/str.c 2020/06/15 14:46:28 1.48
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: str.c,v 1.47 2020/06/14 23:13:21 rillig Exp $ */ 1/* $NetBSD: str.c,v 1.48 2020/06/15 14:46:28 rillig Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1988, 1989, 1990, 1993 4 * Copyright (c) 1988, 1989, 1990, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor. 8 * Adam de Boor.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -59,34 +59,34 @@ @@ -59,34 +59,34 @@
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE. 68 * SUCH DAMAGE.
69 */ 69 */
70 70
71#ifndef MAKE_NATIVE 71#ifndef MAKE_NATIVE
72static char rcsid[] = "$NetBSD: str.c,v 1.47 2020/06/14 23:13:21 rillig Exp $"; 72static char rcsid[] = "$NetBSD: str.c,v 1.48 2020/06/15 14:46:28 rillig Exp $";
73#else 73#else
74#include <sys/cdefs.h> 74#include <sys/cdefs.h>
75#ifndef lint 75#ifndef lint
76#if 0 76#if 0
77static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90"; 77static char sccsid[] = "@(#)str.c 5.8 (Berkeley) 6/1/90";
78#else 78#else
79__RCSID("$NetBSD: str.c,v 1.47 2020/06/14 23:13:21 rillig Exp $"); 79__RCSID("$NetBSD: str.c,v 1.48 2020/06/15 14:46:28 rillig Exp $");
80#endif 80#endif
81#endif /* not lint */ 81#endif /* not lint */
82#endif 82#endif
83 83
84#include "make.h" 84#include "make.h"
85 85
86/*- 86/*-
87 * str_concat -- 87 * str_concat --
88 * concatenate the two strings, inserting a space or slash between them, 88 * concatenate the two strings, inserting a space or slash between them,
89 * freeing them if requested. 89 * freeing them if requested.
90 * 90 *
91 * returns -- 91 * returns --
92 * the resulting string in allocated space. 92 * the resulting string in allocated space.
@@ -345,26 +345,28 @@ Str_Match(const char *string, const char @@ -345,26 +345,28 @@ Str_Match(const char *string, const char
345 */ 345 */
346 if (*pattern == 0) 346 if (*pattern == 0)
347 return !*string; 347 return !*string;
348 if (*string == 0 && *pattern != '*') 348 if (*string == 0 && *pattern != '*')
349 return 0; 349 return 0;
350 /* 350 /*
351 * Check for a "*" as the next pattern character. It matches 351 * Check for a "*" as the next pattern character. It matches
352 * any substring. We handle this by calling ourselves 352 * any substring. We handle this by calling ourselves
353 * recursively for each postfix of string, until either we 353 * recursively for each postfix of string, until either we
354 * match or we reach the end of the string. 354 * match or we reach the end of the string.
355 */ 355 */
356 if (*pattern == '*') { 356 if (*pattern == '*') {
357 pattern++; 357 pattern++;
 358 while (*pattern == '*')
 359 pattern++;
358 if (*pattern == 0) 360 if (*pattern == 0)
359 return 1; 361 return 1;
360 while (*string != 0) { 362 while (*string != 0) {
361 if (Str_Match(string, pattern)) 363 if (Str_Match(string, pattern))
362 return 1; 364 return 1;
363 ++string; 365 ++string;
364 } 366 }
365 return 0; 367 return 0;
366 } 368 }
367 /* 369 /*
368 * Check for a "?" as the next pattern character. It matches 370 * Check for a "?" as the next pattern character. It matches
369 * any single character. 371 * any single character.
370 */ 372 */

cvs diff -r1.5 -r1.6 src/usr.bin/make/unit-tests/Attic/modmatch.mk (expand / switch to unified diff)

--- src/usr.bin/make/unit-tests/Attic/modmatch.mk 2020/06/14 23:13:21 1.5
+++ src/usr.bin/make/unit-tests/Attic/modmatch.mk 2020/06/15 14:46:28 1.6
@@ -26,14 +26,14 @@ show: @@ -26,14 +26,14 @@ show:
26 @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a is "${X_LIBS:M*/lib${LIB}.a}"' 26 @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a is "${X_LIBS:M*/lib${LIB}.a}"'
27 @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a:tu is "${X_LIBS:M*/lib${LIB}.a:tu}"' 27 @echo 'LIB=${LIB} X_LIBS:M*/lib$${LIB}.a:tu is "${X_LIBS:M*/lib${LIB}.a:tu}"'
28 28
29LIST= One Two Three Four five six seven 29LIST= One Two Three Four five six seven
30 30
31check-cclass: 31check-cclass:
32 @echo Upper=${LIST:M[A-Z]*} 32 @echo Upper=${LIST:M[A-Z]*}
33 @echo Lower=${LIST:M[^A-Z]*} 33 @echo Lower=${LIST:M[^A-Z]*}
34 @echo nose=${LIST:M[^s]*[ex]} 34 @echo nose=${LIST:M[^s]*[ex]}
35 35
36# Before 2020-06-13, this expression took quite a long time in Str_Match, 36# Before 2020-06-13, this expression took quite a long time in Str_Match,
37# calling itself 601080390 times for 16 asterisks. 37# calling itself 601080390 times for 16 asterisks.
38slow: .PHONY 38slow: .PHONY
39# @:;: ${:U****************:M****************b:Q} 39 @:;: ${:U****************:M****************b:Q}