Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/usr.bin/make make(1): fix edge case in := with undefined in ...
details: https://anonhg.NetBSD.org/src/rev/94712cfc60f7
branches: trunk
changeset: 958178:94712cfc60f7
user: rillig <rillig%NetBSD.org@localhost>
date: Sun Dec 27 22:29:37 2020 +0000
description:
make(1): fix edge case in := with undefined in variable name
Previously, the assignment "VAR${UNDEF} := value" actually assigned to 2
variables. See var-op-expand.mk for details.
diffstat:
usr.bin/make/parse.c | 19 +++++--------------
usr.bin/make/unit-tests/var-op-expand.mk | 25 ++++++++++++-------------
2 files changed, 17 insertions(+), 27 deletions(-)
diffs (96 lines):
diff -r bdcd1d11789c -r 94712cfc60f7 usr.bin/make/parse.c
--- a/usr.bin/make/parse.c Sun Dec 27 21:31:27 2020 +0000
+++ b/usr.bin/make/parse.c Sun Dec 27 22:29:37 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.519 2020/12/27 18:22:28 rillig Exp $ */
+/* $NetBSD: parse.c,v 1.520 2020/12/27 22:29:37 rillig Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1993
@@ -117,7 +117,7 @@
#include "pathnames.h"
/* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: parse.c,v 1.519 2020/12/27 18:22:28 rillig Exp $");
+MAKE_RCSID("$NetBSD: parse.c,v 1.520 2020/12/27 22:29:37 rillig Exp $");
/* types and constants */
@@ -1931,17 +1931,6 @@
char *evalue;
Boolean savedPreserveUndefined = preserveUndefined;
- /* TODO: Can this assignment to preserveUndefined be moved further down
- * to the actually interesting Var_Subst call, without affecting any
- * edge cases?
- *
- * It might affect the implicit expansion of the variable name in the
- * Var_Exists and Var_Set calls, even though it's unlikely that anyone
- * cared about this edge case when adding this code. In addition,
- * variable assignments should not refer to any undefined variables in
- * the variable name. */
- preserveUndefined = TRUE;
-
/*
* make sure that we set the variable the first time to nothing
* so that it gets substituted!
@@ -1949,9 +1938,11 @@
if (!Var_Exists(name, ctxt))
Var_Set(name, "", ctxt);
+ preserveUndefined = TRUE;
(void)Var_Subst(uvalue, ctxt, VARE_WANTRES | VARE_KEEP_DOLLAR, &evalue);
+ preserveUndefined = savedPreserveUndefined;
/* TODO: handle errors */
- preserveUndefined = savedPreserveUndefined;
+
avalue = evalue;
Var_Set(name, avalue, ctxt);
diff -r bdcd1d11789c -r 94712cfc60f7 usr.bin/make/unit-tests/var-op-expand.mk
--- a/usr.bin/make/unit-tests/var-op-expand.mk Sun Dec 27 21:31:27 2020 +0000
+++ b/usr.bin/make/unit-tests/var-op-expand.mk Sun Dec 27 22:29:37 2020 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: var-op-expand.mk,v 1.7 2020/12/27 21:31:27 rillig Exp $
+# $NetBSD: var-op-expand.mk,v 1.8 2020/12/27 22:29:37 rillig Exp $
#
# Tests for the := variable assignment operator, which expands its
# right-hand side.
@@ -116,26 +116,25 @@
.endif
-# XXX: edge case: When a variable name refers to an undefined variable, the
-# behavior differs between the '=' and the ':=' assignment operators.
-# This bug exists since var.c 1.42 from 2000-05-11.
+# Between var.c 1.42 from 2000-05-11 and before parse.c 1.520 from 2020-12-27,
+# if the variable name in a ':=' assignment referred to an undefined variable,
+# there were actually 2 assignments to different variables:
#
-# The '=' operator expands the undefined variable to an empty string, thus
-# assigning to VAR_ASSIGN_. In the name of variables to be set, it should
-# really be forbidden to refer to undefined variables.
+# Global["VAR_SUBST_${UNDEF}"] = ""
+# Global["VAR_SUBST_"] = ""
#
-# The ':=' operator expands the variable name twice. In one of these
-# expansions, the undefined variable expression is preserved (controlled by
-# preserveUndefined in VarAssign_EvalSubst), in the other expansion it expands
-# to an empty string. This way, 2 variables are created using a single
-# variable assignment. It's magic. :-/
+# The variable name with the empty value actually included a dollar sign.
+# Variable names with dollars are not used in practice.
+#
+# It might be a good idea to forbid undefined variables on the left-hand side
+# of a variable assignment.
.undef UNDEF
VAR_ASSIGN_${UNDEF}= assigned by '='
VAR_SUBST_${UNDEF}:= assigned by ':='
.if ${VAR_ASSIGN_} != "assigned by '='"
. error
.endif
-.if ${${:UVAR_SUBST_\${UNDEF\}}} != ""
+.if defined(${:UVAR_SUBST_\${UNDEF\}})
. error
.endif
.if ${VAR_SUBST_} != "assigned by ':='"
Home |
Main Index |
Thread Index |
Old Index