Sun Mar 14 10:57:13 2021 UTC ()
make: fix wrong expression evaluation in -dL mode

The modifier ':C' now only compiles the regular expression if the result
of the expression is actually needed.

Several other modifiers have the same bug of evaluating the expression
in cases where this is not needed.  It just doesn't show up because they
don't have any noticeable side effects, other than wasting CPU time.
This affects irrelevant conditions as well.


(rillig)
diff -r1.855 -r1.856 src/usr.bin/make/var.c
diff -r1.15 -r1.16 src/usr.bin/make/unit-tests/opt-debug-lint.exp
diff -r1.13 -r1.14 src/usr.bin/make/unit-tests/opt-debug-lint.mk

cvs diff -r1.855 -r1.856 src/usr.bin/make/var.c (expand / switch to context diff)
--- src/usr.bin/make/var.c 2021/02/23 16:29:52 1.855
+++ src/usr.bin/make/var.c 2021/03/14 10:57:12 1.856
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.855 2021/02/23 16:29:52 rillig Exp $	*/
+/*	$NetBSD: var.c,v 1.856 2021/03/14 10:57:12 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -140,7 +140,7 @@
 #include "metachar.h"
 
 /*	"@(#)var.c	8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.855 2021/02/23 16:29:52 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.856 2021/03/14 10:57:12 rillig Exp $");
 
 typedef enum VarFlags {
 	VFL_NONE	= 0,
@@ -2890,6 +2890,12 @@
 			oneBigWord = TRUE;
 		else
 			break;
+	}
+
+	if (!(st->expr->eflags & VARE_WANTRES)) {
+		free(args.replace);
+		free(re);
+		return AMR_OK;
 	}
 
 	error = regcomp(&args.re, re, REG_EXTENDED);

cvs diff -r1.15 -r1.16 src/usr.bin/make/unit-tests/opt-debug-lint.exp (expand / switch to context diff)
--- src/usr.bin/make/unit-tests/opt-debug-lint.exp 2021/03/14 10:45:51 1.15
+++ src/usr.bin/make/unit-tests/opt-debug-lint.exp 2021/03/14 10:57:12 1.16
@@ -3,7 +3,6 @@
 make: "opt-debug-lint.mk" line 61: Missing delimiter ':' after modifier "L"
 make: "opt-debug-lint.mk" line 61: Missing delimiter ':' after modifier "P"
 make: "opt-debug-lint.mk" line 69: Unknown modifier "${"
-make: Regex compilation error: (details omitted)
 make: Fatal errors encountered -- cannot continue
 make: stopped in unit-tests
 exit status 1

cvs diff -r1.13 -r1.14 src/usr.bin/make/unit-tests/opt-debug-lint.mk (expand / switch to context diff)
--- src/usr.bin/make/unit-tests/opt-debug-lint.mk 2021/03/14 10:45:51 1.13
+++ src/usr.bin/make/unit-tests/opt-debug-lint.mk 2021/03/14 10:57:12 1.14
@@ -1,4 +1,4 @@
-# $NetBSD: opt-debug-lint.mk,v 1.13 2021/03/14 10:45:51 rillig Exp $
+# $NetBSD: opt-debug-lint.mk,v 1.14 2021/03/14 10:57:12 rillig Exp $
 #
 # Tests for the -dL command line option, which runs additional checks
 # to catch common mistakes, such as unclosed variable expressions.
@@ -77,12 +77,15 @@
 .  error
 .endif
 
-# Before var.c 1.XXX from 2021-03-14, the whole variable text was evaluated
-# to check for unclosed expressions and unknown operators.  During this check,
-# the subexpression '${:U2}' was not expanded, instead it was copied verbatim
-# into the regular expression, which was '.*=.{1,${:U2}}$'.  This regular
-# expression was then compiled (despite VARE_WANTRES being unset), which
-# resulted in a wrong error message.
+# In lint mode, the whole variable text is evaluated to check for unclosed
+# expressions and unknown operators.  During this check, the subexpression
+# '${:U2}' is not expanded, instead it is copied verbatim into the regular
+# expression, leading to '.*=.{1,${:U2}}$'.
+#
+# Before var.c 1.856 from 2021-03-14, this regular expression was then
+# compiled even though that was not necessary for checking the syntax at the
+# level of variable expressions.  The unexpanded '$' then resulted in a wrong
+# error message.
 #
 # This only happened in lint mode since in default mode the early check for
 # unclosed expressions and unknown modifiers is skipped.