Module Name: src Committed By: rillig Date: Sat Nov 13 18:37:42 UTC 2021
Modified Files: src/usr.bin/make/unit-tests: var-op-expand.exp var-op-expand.mk Log Message: tests/make: test double indirection in ':=' with undefined variable Reported by Simon J Gerraty via private mail. This edge case has been handled in essentially the same way since at least 2000-05-30, probably several years earlier as well. The test file is: ---- snip ---- .undef LATER .undef later INDIRECT:= ${LATER:S,value,replaced,} indirect:= ${INDIRECT:C,S,s,} # expect+1: Unknown modifier "s,value,replaced," .if ${indirect} != "" . error .else . warning XXX Neither branch should be taken. .endif LATER= uppercase-value later= lowercase-value # expect+1: Unknown modifier "s,value,replaced," .if ${indirect} != "uppercase-replaced" . warning XXX Neither branch should be taken. .else . error .endif all: @:; ---- snap ---- The output from 'make -r -f later.mk' is: make-2000.05.30.02.32.21 | make: Unknown modifier 's' | | "later.mk", line 9: Need an operator | make: Unknown modifier 's' | | "later.mk", line 15: Need an operator | Fatal errors encountered -- cannot continue | exit status 1 make-2000.12.30.16.38.22 The pathnames in the error message gets absolute: make-2001.01.23.02.48.05 | make: Unknown modifier 's' | | ".../later.mk", line 9: Need an operator | make: Unknown modifier 's' | | ".../later.mk", line 15: Need an operator | Fatal errors encountered -- cannot continue | exit status 1 make-2001.01.23.02.48.05 All error messages get 'make:' as a common prefix: make-2001.02.23.21.11.38 | make: Unknown modifier 's' | | make: ".../later.mk" line 9: Need an operator | make: Unknown modifier 's' | | make: ".../later.mk" line 15: Need an operator | make: Fatal errors encountered -- cannot continue | exit status 1 make-2001.05.29.17.37.52 The 'stopped in' gets added: make-2001.06.12.23.36.18 | make: Unknown modifier 's' | | make: ".../later.mk" line 9: Need an operator | make: Unknown modifier 's' | | make: ".../later.mk" line 15: Need an operator | make: Fatal errors encountered -- cannot continue | | make: stopped in ... | exit status 1 make-2002.02.21.22.21.34 The empty lines between the error messages get removed. make-2002.03.21.11.42.21 | make: Unknown modifier 's' | make: ".../later.mk" line 9: Need an operator | make: Unknown modifier 's' | make: ".../later.mk" line 15: Need an operator | make: Fatal errors encountered -- cannot continue | | make: stopped in ... | exit status 1 make-2009.10.15.02.27.44 The error message for unknown directives gets more helpful: make-2009.11.19.06.48.37 | make: Unknown modifier 's' | make: ".../later.mk" line 9: Unknown directive | make: Unknown modifier 's' | make: ".../later.mk" line 15: Unknown directive | make: Fatal errors encountered -- cannot continue | | make: stopped in ... | exit status 1 make-2010.02.22.19.20.33 The directives '.error', '.warning' and '.info' get added: make-2010.04.29.23.12.21 | make: Unknown modifier 's' | make: ".../later.mk" line 9: warning: XXX Neither branch should be taken. | make: Unknown modifier 's' | make: ".../later.mk" line 15: warning: XXX Neither branch should be taken. | exit status 0 make-2020.12.20.19.37.23 The error message about an unknown variable modifier gets line number information: make-2020.12.20.19.47.34 | make: ".../later.mk" line 6: Unknown modifier 's' | make: ".../later.mk" line 9: warning: XXX Neither branch should be taken. | make: ".../later.mk" line 14: Unknown modifier 's' | make: ".../later.mk" line 15: warning: XXX Neither branch should be taken. | make: Fatal errors encountered -- cannot continue | make: stopped in ... | exit status 1 make-2021.02.23.15.07.58 The error message about an unknown variable modifier gets more context than only a single letter: make-2021.02.23.15.19.41 | make: ".../later.mk" line 6: Unknown modifier "s,value,replaced," | make: ".../later.mk" line 9: warning: XXX Neither branch should be taken. | make: ".../later.mk" line 14: Unknown modifier "s,value,replaced," | make: ".../later.mk" line 15: warning: XXX Neither branch should be taken. | make: Fatal errors encountered -- cannot continue | make: stopped in ... | exit status 1 To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/usr.bin/make/unit-tests/var-op-expand.exp cvs rdiff -u -r1.11 -r1.12 src/usr.bin/make/unit-tests/var-op-expand.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/var-op-expand.exp diff -u src/usr.bin/make/unit-tests/var-op-expand.exp:1.3 src/usr.bin/make/unit-tests/var-op-expand.exp:1.4 --- src/usr.bin/make/unit-tests/var-op-expand.exp:1.3 Sun Dec 27 21:31:27 2020 +++ src/usr.bin/make/unit-tests/var-op-expand.exp Sat Nov 13 18:37:42 2021 @@ -1 +1,7 @@ -exit status 0 +make: "var-op-expand.mk" line 229: Unknown modifier "s,value,replaced," +make: "var-op-expand.mk" line 232: warning: XXX Neither branch should be taken. +make: "var-op-expand.mk" line 237: Unknown modifier "s,value,replaced," +make: "var-op-expand.mk" line 238: warning: XXX Neither branch should be taken. +make: Fatal errors encountered -- cannot continue +make: stopped in unit-tests +exit status 1 Index: src/usr.bin/make/unit-tests/var-op-expand.mk diff -u src/usr.bin/make/unit-tests/var-op-expand.mk:1.11 src/usr.bin/make/unit-tests/var-op-expand.mk:1.12 --- src/usr.bin/make/unit-tests/var-op-expand.mk:1.11 Fri Jan 1 23:07:48 2021 +++ src/usr.bin/make/unit-tests/var-op-expand.mk Sat Nov 13 18:37:42 2021 @@ -1,4 +1,4 @@ -# $NetBSD: var-op-expand.mk,v 1.11 2021/01/01 23:07:48 sjg Exp $ +# $NetBSD: var-op-expand.mk,v 1.12 2021/11/13 18:37:42 rillig Exp $ # # Tests for the := variable assignment operator, which expands its # right-hand side. @@ -174,5 +174,72 @@ VAR_SUBST_${UNDEF}:= assigned by ':=' . error .endif + +# The following test case demonstrates that the variable 'LATER' is preserved +# in the ':=' assignment since the variable 'LATER' is not yet defined. +# After the assignment to 'LATER', evaluating the variable 'INDIRECT' +# evaluates 'LATER' as well. +# +.undef LATER +INDIRECT:= ${LATER:S,value,replaced,} +.if ${INDIRECT} != "" +. error +.endif +LATER= late-value +.if ${INDIRECT} != "late-replaced" +. error +.endif + + +# Same as the test case above, except for the additional modifier ':tl' when +# evaluating the variable 'INDIRECT'. Nothing surprising here. +.undef LATER +.undef later +INDIRECT:= ${LATER:S,value,replaced,} +.if ${INDIRECT:tl} != "" +. error +.endif +LATER= uppercase-value +later= lowercase-value +.if ${INDIRECT:tl} != "uppercase-replaced" +. error +.endif + + +# Similar to the two test cases above, the situation gets a bit more involved +# here, due to the double indirection. The variable 'indirect' is supposed to +# be the lowercase version of the variable 'INDIRECT'. +# +# The assignment operator ':=' for the variable 'INDIRECT' could be a '=' as +# well, it wouldn't make a difference in this case. The crucial detail is the +# assignment operator ':=' for the variable 'indirect', though. During this +# assignment, the variable modifier ':S,value,replaced,' is converted to +# lowercase, which turns 'S' into 's', thus producing an unknown modifier. +# In this case, make issues a warning, but in cases where the modifier +# includes a '=', the modifier would be interpreted as a SysV-style +# substitution like '.c=.o', and make would not issue a warning, leading to +# silent unexpected behavior. +# +# As of 2021-11-13, the actual behavior is unexpected though since +.undef LATER +.undef later +INDIRECT:= ${LATER:S,value,replaced,} +indirect:= ${INDIRECT:tl} +# expect+1: Unknown modifier "s,value,replaced," +.if ${indirect} != "" +. error +.else +. warning XXX Neither branch should be taken. +.endif +LATER= uppercase-value +later= lowercase-value +# expect+1: Unknown modifier "s,value,replaced," +.if ${indirect} != "uppercase-replaced" +. warning XXX Neither branch should be taken. +.else +. error +.endif + + all: @:;