Module Name:    src
Committed By:   rillig
Date:           Tue Sep  7 20:41:58 UTC 2021

Modified Files:
        src/usr.bin/make/unit-tests: cond-short.mk var-eval-short.exp
            var-eval-short.mk

Log Message:
tests/make: expand on the history of unnecessary evaluation


To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/usr.bin/make/unit-tests/cond-short.mk
cvs rdiff -u -r1.13 -r1.14 src/usr.bin/make/unit-tests/var-eval-short.exp
cvs rdiff -u -r1.6 -r1.7 src/usr.bin/make/unit-tests/var-eval-short.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/unit-tests/cond-short.mk
diff -u src/usr.bin/make/unit-tests/cond-short.mk:1.16 src/usr.bin/make/unit-tests/cond-short.mk:1.17
--- src/usr.bin/make/unit-tests/cond-short.mk:1.16	Sun Mar 14 11:49:37 2021
+++ src/usr.bin/make/unit-tests/cond-short.mk	Tue Sep  7 20:41:58 2021
@@ -1,4 +1,4 @@
-# $NetBSD: cond-short.mk,v 1.16 2021/03/14 11:49:37 rillig Exp $
+# $NetBSD: cond-short.mk,v 1.17 2021/09/07 20:41:58 rillig Exp $
 #
 # Demonstrates that in conditions, the right-hand side of an && or ||
 # is only evaluated if it can actually influence the result.
@@ -12,7 +12,20 @@
 # possible to skip evaluation of irrelevant variable expressions and only
 # parse them.  They were still evaluated though, the only difference to
 # relevant variable expressions was that in the irrelevant variable
-# expressions, undefined variables were allowed.
+# expressions, undefined variables were allowed.  This allowed for conditions
+# like 'defined(VAR) && ${VAR:S,from,to,} != ""', which no longer produced an
+# error message 'Malformed conditional', but it still evaluated the
+# expression, even though the expression was irrelevant.
+#
+# Since the initial commit on 1993-03-21, the manual page has been saying that
+# make 'will only evaluate a conditional as far as is necessary to determine',
+# but that was wrong.  The code in cond.c 1.1 from 1993-03-21 looks good since
+# it calls Var_Parse(condExpr, VAR_CMD, doEval,&varSpecLen,&doFree), but the
+# definition of Var_Parse does not call the third parameter 'doEval', as would
+# be expected, but instead 'err', accompanied by the comment 'TRUE if
+# undefined variables are an error'.  This subtle difference between 'do not
+# evaluate at all' and 'allow undefined variables' led to the unexpected
+# evaluation.
 #
 # See also:
 #	var-eval-short.mk, for short-circuited variable modifiers

Index: src/usr.bin/make/unit-tests/var-eval-short.exp
diff -u src/usr.bin/make/unit-tests/var-eval-short.exp:1.13 src/usr.bin/make/unit-tests/var-eval-short.exp:1.14
--- src/usr.bin/make/unit-tests/var-eval-short.exp:1.13	Mon Apr  5 13:35:41 2021
+++ src/usr.bin/make/unit-tests/var-eval-short.exp	Tue Sep  7 20:41:58 2021
@@ -1,16 +1,16 @@
 make: "var-eval-short.mk" line 41: In the :@ modifier of "", the variable name "${FAIL}" must not contain a dollar.
 make: "var-eval-short.mk" line 41: Malformed conditional (0 && ${:Uword:@${FAIL}@expr@})
-make: "var-eval-short.mk" line 79: Invalid time value: ${FAIL}}
-make: "var-eval-short.mk" line 79: Malformed conditional (0 && ${:Uword:gmtime=${FAIL}})
-make: "var-eval-short.mk" line 93: Invalid time value: ${FAIL}}
-make: "var-eval-short.mk" line 93: Malformed conditional (0 && ${:Uword:localtime=${FAIL}})
+make: "var-eval-short.mk" line 81: Invalid time value: ${FAIL}}
+make: "var-eval-short.mk" line 81: Malformed conditional (0 && ${:Uword:gmtime=${FAIL}})
+make: "var-eval-short.mk" line 95: Invalid time value: ${FAIL}}
+make: "var-eval-short.mk" line 95: Malformed conditional (0 && ${:Uword:localtime=${FAIL}})
 CondParser_Eval: 0 && ${0:?${FAIL}then:${FAIL}else}
 Var_Parse: ${0:?${FAIL}then:${FAIL}else} (parse-only)
 Parsing modifier ${0:?...}
 Modifier part: "${FAIL}then"
 Modifier part: "${FAIL}else"
 Result of ${0:?${FAIL}then:${FAIL}else} is "" (parse-only, defined)
-ParseReadLine (158): 'DEFINED=	defined'
+ParseReadLine (160): 'DEFINED=	defined'
 Global: DEFINED = defined
 CondParser_Eval: 0 && ${DEFINED:L:?${FAIL}then:${FAIL}else}
 Var_Parse: ${DEFINED:L:?${FAIL}then:${FAIL}else} (parse-only)
@@ -20,7 +20,7 @@ Parsing modifier ${DEFINED:?...}
 Modifier part: "${FAIL}then"
 Modifier part: "${FAIL}else"
 Result of ${DEFINED:?${FAIL}then:${FAIL}else} is "defined" (parse-only, regular)
-ParseReadLine (161): '.MAKEFLAGS: -d0'
+ParseReadLine (163): '.MAKEFLAGS: -d0'
 ParseDependency(.MAKEFLAGS: -d0)
 Global: .MAKEFLAGS =  -r -k -d cpv -d
 Global: .MAKEFLAGS =  -r -k -d cpv -d 0

Index: src/usr.bin/make/unit-tests/var-eval-short.mk
diff -u src/usr.bin/make/unit-tests/var-eval-short.mk:1.6 src/usr.bin/make/unit-tests/var-eval-short.mk:1.7
--- src/usr.bin/make/unit-tests/var-eval-short.mk:1.6	Mon Sep  6 19:38:30 2021
+++ src/usr.bin/make/unit-tests/var-eval-short.mk	Tue Sep  7 20:41:58 2021
@@ -1,4 +1,4 @@
-# $NetBSD: var-eval-short.mk,v 1.6 2021/09/06 19:38:30 rillig Exp $
+# $NetBSD: var-eval-short.mk,v 1.7 2021/09/07 20:41:58 rillig Exp $
 #
 # Tests for each variable modifier to ensure that they only do the minimum
 # necessary computations.  If the result of the expression is not needed, they
@@ -59,10 +59,12 @@ FAIL=	${:!echo unexpected 1>&2!}
 .endif
 
 # Before var.c 1.856 from 2021-03-14, the modifier ':C' did not expand the
-# nested expression ${FAIL} and then tried to compile the unexpanded text as a
-# regular expression, which failed both because of the '{FAIL}', which is not
-# a valid repetition, and because of the '****', which are repeated
-# repetitions as well.
+# nested expression ${FAIL}, which is correct, and then tried to compile the
+# unexpanded text as a regular expression, which is unnecessary since the
+# right-hand side of the '&&' cannot influence the outcome of the condition.
+# Compiling the regular expression then failed both because of the '{FAIL}',
+# which is not a valid repetition of the form '{1,5}', and because of the
+# '****', which are repeated repetitions as well.
 # '${FAIL}'
 .if 0 && ${:Uword:C,${FAIL}****,,}
 .endif

Reply via email to