[SV 59870] define/undefine prerequisites are not target-specific vars

* src/read.c (parse_var_assignment): If called in a target-specific
variable context don't allow define/undefine as variable assignments.
* test/scripts/variables/define: Add a test.
* test/scripts/variables/undefine: Add a test.
This commit is contained in:
Paul Smith 2021-03-14 16:32:47 -04:00
parent d9aff6b817
commit da6fc6aae2
3 changed files with 41 additions and 5 deletions

View file

@ -494,7 +494,7 @@ eval_buffer (char *buffer, const floc *flocp)
based on the modifiers found if any, plus V_ASSIGN is 1. based on the modifiers found if any, plus V_ASSIGN is 1.
*/ */
static char * static char *
parse_var_assignment (const char *line, struct vmodifiers *vmod) parse_var_assignment (const char *line, int targvar, struct vmodifiers *vmod)
{ {
const char *p; const char *p;
memset (vmod, '\0', sizeof (*vmod)); memset (vmod, '\0', sizeof (*vmod));
@ -529,14 +529,14 @@ parse_var_assignment (const char *line, struct vmodifiers *vmod)
vmod->override_v = 1; vmod->override_v = 1;
else if (word1eq ("private")) else if (word1eq ("private"))
vmod->private_v = 1; vmod->private_v = 1;
else if (word1eq ("define")) else if (!targvar && word1eq ("define"))
{ {
/* We can't have modifiers after 'define' */ /* We can't have modifiers after 'define' */
vmod->define_v = 1; vmod->define_v = 1;
p = next_token (p2); p = next_token (p2);
break; break;
} }
else if (word1eq ("undefine")) else if (!targvar && word1eq ("undefine"))
{ {
/* We can't have modifiers after 'undefine' */ /* We can't have modifiers after 'undefine' */
vmod->undefine_v = 1; vmod->undefine_v = 1;
@ -721,7 +721,7 @@ eval (struct ebuffer *ebuf, int set_default)
/* See if this is a variable assignment. We need to do this early, to /* See if this is a variable assignment. We need to do this early, to
allow variables with names like 'ifdef', 'export', 'private', etc. */ allow variables with names like 'ifdef', 'export', 'private', etc. */
p = parse_var_assignment (p, &vmod); p = parse_var_assignment (p, 0, &vmod);
if (vmod.assign_v) if (vmod.assign_v)
{ {
struct variable *v; struct variable *v;
@ -1181,7 +1181,7 @@ eval (struct ebuffer *ebuf, int set_default)
p2 = variable_buffer + l; p2 = variable_buffer + l;
} }
p2 = parse_var_assignment (p2, &vmod); p2 = parse_var_assignment (p2, 1, &vmod);
if (vmod.assign_v) if (vmod.assign_v)
{ {
/* If there was a semicolon found, add it back, plus anything /* If there was a semicolon found, add it back, plus anything

View file

@ -279,4 +279,22 @@ hello
world world
'); ');
# Ensure that define can be a target when not appearing in a variable
# definition context. See SV 59870
run_make_test(q!
define = define
$(define) : ;@echo $@
%:define
all: define foo
%.x : define
foo:;
!,
'', "define\n");
1; 1;

View file

@ -70,4 +70,22 @@ all: ;@echo ouch
', ',
'', "#MAKEFILE#:3: *** empty variable name. Stop.\n", 512); '', "#MAKEFILE#:3: *** empty variable name. Stop.\n", 512);
# Ensure that define can be a target when not appearing in a variable
# definition context. See SV 59870
run_make_test(q!
undefine = undefine
$(undefine) : ;@echo $@
%:undefine
all: undefine foo
%.x : undefine
foo:;
!,
'', "undefine\n");
1; 1;