ash: eval: Always set localvar_stop
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 20 Feb 2020 09:33:38 +0000 (10:33 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 20 Feb 2020 09:37:30 +0000 (10:37 +0100)
Upstream commit:

    Date: Thu, 31 May 2018 01:15:34 +0800
    eval: Always set localvar_stop

    The variable localvar_stop is set iff vlocal is true.  gcc doesn't
    get this so we get a spurious warning.

    This patch fixes this by always calling pushlocalvars with vlocal
    and making it only actually do the push if vlocal is non-zero.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
shell/ash.c

index 5bb10e5cbc7e1f0bbca7582abc709b8eee886377..81d2422d69405bc2fddc9d57d8e8a3c269fc5c4a 100644 (file)
@@ -9722,18 +9722,23 @@ poplocalvars(int keep)
  * Create a new localvar environment.
  */
 static struct localvar_list *
-pushlocalvars(void)
+pushlocalvars(int push)
 {
        struct localvar_list *ll;
+       struct localvar_list *top;
+
+       top = localvar_stack;
+       if (!push)
+               goto out;
 
        INT_OFF;
        ll = ckzalloc(sizeof(*ll));
        /*ll->lv = NULL; - zalloc did it */
-       ll->next = localvar_stack;
+       ll->next = top;
        localvar_stack = ll;
        INT_ON;
-
-       return ll->next;
+ out:
+       return top;
 }
 
 static void
@@ -10217,6 +10222,8 @@ evalcommand(union node *cmd, int flags)
                        vflags = VEXPORT;
        }
 
+       localvar_stop = pushlocalvars(vlocal);
+
        /* Reserve one extra spot at the front for shellexec. */
        nargv = stalloc(sizeof(char *) * (argc + 2));
        argv = ++nargv;
@@ -10245,7 +10252,6 @@ evalcommand(union node *cmd, int flags)
        status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
 
        if (status) {
-               vlocal = 0;
  bail:
                exitstatus = status;
 
@@ -10256,10 +10262,6 @@ evalcommand(union node *cmd, int flags)
                goto out;
        }
 
-       localvar_stop = NULL;
-       if (vlocal)
-               localvar_stop = pushlocalvars();
-
        for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
                struct strlist **spp;
 
@@ -10410,8 +10412,7 @@ evalcommand(union node *cmd, int flags)
                popredir(/*drop:*/ cmd_is_exec);
        unwindredir(redir_stop);
        unwindfiles(file_stop);
-       if (vlocal)
-               unwindlocalvars(localvar_stop);
+       unwindlocalvars(localvar_stop);
        if (lastarg) {
                /* dsl: I think this is intended to be used to support
                 * '_' in 'vi' command mode during line editing...