bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Unable to dereference function-local nameref to global variable of s


From: Piotr Grzybowski
Subject: Re: Unable to dereference function-local nameref to global variable of same name
Date: Thu, 11 Aug 2016 23:10:41 +0200

Hi,

 since we already allow circular refs in the variable_context, the below 
answers your request. It means: in the function scope the name references to 
existing global variables will be correctly resolved. Please note that using 
find_global_variable in global_variable=find_global_variable(newname); results 
in breaking of the test suite (infinite recursion I think). As it is now, I am 
sure, it will result in Grisha's report with the chain of global namerefs, that 
is, currently it works like this:

# declare -n ref="HOME"; declare -n ref2=ref; f() { declare -n ref2="$1"; echo 
$ref2; }; f ref2;
bash: declare: warning: ref2: circular name reference
bash: warning: ref2: circular name reference
ref

and with find_global_variable:

# declare -n ref="HOME"; declare -n ref2=ref; f() { declare -n ref2="$1"; echo 
$ref2; }; f ref2;
bash: declare: warning: ref2: circular name reference
bash: warning: ref2: circular name reference
/Users/merlin

 I personally believe that we should make this change (of course not before 4.4 
;-)), and that it should follow the global nameref chain.
 The patch (not breaking the test suite) follows.


diff --git a/variables.c b/variables.c
index be2446e..14f1be7 100644
--- a/variables.c
+++ b/variables.c
@@ -1906,6 +1906,7 @@ find_variable_nameref (v)
   int level, flags;
   char *newname, *t;
   SHELL_VAR *orig, *oldv;
+  SHELL_VAR *global_variable;
 
   level = 0;
   orig = v;
@@ -1925,6 +1926,11 @@ find_variable_nameref (v)
       v = find_variable_internal (newname, flags);
       if (v == orig || v == oldv)
        {
+         global_variable=find_global_variable_noref(newname);
+         if (global_variable&&variable_context)
+           {
+             return global_variable;
+           }
          internal_warning (_("%s: circular name reference"), orig->name);
          return ((SHELL_VAR *)0);
        }


cheers,
pg



On 10 Aug 2016, at 18:06, Andreas Kusalananda Kähäri wrote:

> Configuration Information [Automatically generated, do not change]:
> Machine: x86_64
> OS: openbsd6.0
> Compiler: cc
> Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
> -DCONF_OSTYPE='openbsd6.0' -DCONF_MACHTYPE='x86_64-unknown-openbsd6.0' 
> -DCONF_VENDOR='unknown' -DLOCALEDIR='/usr/local/share/locale' 
> -DPACKAGE='bash' -DSHELL  -DHAVE_CONFIG_H   -I.  -I. -I./include -I./lib  
> -DUSE_MKTEMP -DUSE_MKSTEMP -I/usr/local/include -O2 -pipe
> uname output: OpenBSD uerfale 6.0 GENERIC.MP#38 amd64
> Machine Type: x86_64-unknown-openbsd6.0
> 
> Bash Version: 4.3
> Patch Level: 46
> Release Status: release
> 
> Description:
>    When declaring a variable in a function as a nameref, it can not
>    be dereferenced if the variable it's a nameref to happen to have
>    the same name as the nameref itself.  This imposes unnecessary
>    restrictions on the caller.
> 
>    Also seen in GNU bash, version 4.3.39(1)-release (x86_64-apple-darwin15).
> 
> Repeat-By:
>    function bug {
>        typeset -n var="$1"
>        printf "%s\n" "$var"
>    }
> 
>    var="hello"
>    bug var
> 
>    Result:
>    bash: warning: var: circular name reference
> 
>    Expected result: The string "hello" outputted with a terminating
>    newline (as with ksh93).
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]