Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assigning hashref to symtable not an error since (somewhere before 5.21.10 ) #15409

Open
p5pRT opened this issue Jun 25, 2016 · 6 comments
Open

Comments

@p5pRT
Copy link

p5pRT commented Jun 25, 2016

Migrated from rt.perl.org#128479 (status was 'open')

Searchable as RT128479$

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2016

From @kentfredric

Only managed to narrow it happening between 5.20.0 and 5.21.10 somewhere
as all the perl's I have inbetween broke (libraries went away)

On 5.20.0, the following code is illegal and dies with "Cannot convert a reference to HASH to typeglob at /tmp/wtf.pl line 13."

<--->
#!perl
use strict;
use warnings;

BEGIN {
  my $namespace = do {
  no strict 'refs';
  \%{ 'Foo​::' };
  };
  $namespace->{bar} = { "key" => "value" };
}

print ref Foo​::bar() || 'nothing';

<--->

On 5.21.10+ , Foo​::bar() silently returns undef.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.25.1:

Configured by kent at Sat May 21 11:49:03 NZST 2016.

Summary of my perl5 (revision 5 version 25 subversion 1) configuration:
   
  Platform:
    osname=linux, osvers=4.4.0-gentoo-r1, archname=x86_64-linux
    uname='linux katipo2 4.4.0-gentoo-r1 #33 smp preempt fri jan 29 01:03:50 nzdt 2016 x86_64 intel(r) core(tm) i5-2410m cpu @ 2.30ghz genuineintel gnulinux '
    config_args='-de -Dprefix=/home/kent/perl5/perlbrew/perls/5.25.1-nossp-sdbm-nopmc -Doptimize= -fno-stack-protector -O3 -march=native -mtune=native -Dman1dir=none -Dman3dir=none -Dusedevel -Accflags= -fno-stack-protector -DPERL_HASH_FUNC_SDBM -DPERL_DISABLE_PMC -Aldflags= -fno-stack-protector -Aeval:scriptdir=/home/kent/perl5/perlbrew/perls/5.25.1-nossp-sdbm-nopmc/bin'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fno-stack-protector -DPERL_HASH_FUNC_SDBM -DPERL_DISABLE_PMC -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize=' -fno-stack-protector -O3 -march=native -mtune=native',
    cppflags='-fno-stack-protector -DPERL_HASH_FUNC_SDBM -DPERL_DISABLE_PMC -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong'
    ccversion='', gccversion='5.3.0', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678, doublekind=3
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16, longdblkind=3
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags ='  -fno-stack-protector -fstack-protector-strong -L/usr/local/lib'
    libpth=/usr/lib/gcc/x86_64-pc-linux-gnu/5.3.0/include-fixed /usr/lib /usr/local/lib /lib/../lib64 /usr/lib/../lib64 /lib /lib64 /usr/lib64 /usr/local/lib64
    libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.23.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.23'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared  -fno-stack-protector -O3 -march=native -mtune=native -L/usr/local/lib -fstack-protector-strong'



@INC for perl 5.25.1:
    /home/kent/perl5/perlbrew/perls/5.25.1-nossp-sdbm-nopmc/lib/site_perl/5.25.1/x86_64-linux
    /home/kent/perl5/perlbrew/perls/5.25.1-nossp-sdbm-nopmc/lib/site_perl/5.25.1
    /home/kent/perl5/perlbrew/perls/5.25.1-nossp-sdbm-nopmc/lib/5.25.1/x86_64-linux
    /home/kent/perl5/perlbrew/perls/5.25.1-nossp-sdbm-nopmc/lib/5.25.1
    .


Environment for perl 5.25.1:
    HOME=/home/kent
    LANG=en_NZ.UTF8
    LANGUAGE (unset)
    LC_CTYPE=en_NZ.UTF8
    LC_TIME=en_NZ.UTF8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/kent/perl5/perlbrew/bin:/home/kent/perl5/perlbrew/perls/5.25.1-nossp-sdbm-nopmc/bin:/home/kent/perl5/perlbrew/bin:/home/kent/perl5/perlbrew/perls/5.22.1-nossp-sdbm-nopmc/bin:/home/kent/.perl6/2013.04/bin:/home/kent/.gem/ruby/1.8/bin/:/home/kent/.rvm/gems/ruby-2.1.2/bin:/home/kent/.rvm/gems/ruby-2.1.2@global/bin:/home/kent/.rvm/rubies/ruby-2.1.2/bin:/usr/local/bin:/usr/bin:/bin:/opt/bin:/usr/x86_64-pc-linux-gnu/gcc-bin/5.3.0:/usr/games/bin:/home/kent/.rvm/bin:/home/kent/.rvm/bin
    PERL5LIB=
    PERLBREW_BASHRC_VERSION=0.74
    PERLBREW_HOME=/home/kent/.perlbrew
    PERLBREW_LIB=
    PERLBREW_MANPATH=/home/kent/perl5/perlbrew/perls/5.25.1-nossp-sdbm-nopmc/man
    PERLBREW_PATH=/home/kent/perl5/perlbrew/bin:/home/kent/perl5/perlbrew/perls/5.25.1-nossp-sdbm-nopmc/bin
    PERLBREW_PERL=5.25.1-nossp-sdbm-nopmc
    PERLBREW_ROOT=/home/kent/perl5/perlbrew
    PERLBREW_VERSION=0.74
    PERL_BADLANG (unset)
    PERL_LOCAL_LIB_ROOT=
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2016

From @cpansprout

On Sat Jun 25 00​:09​:09 2016, kentfredric wrote​:

This is a bug report for perl from kentnl@​cpan.org
generated with the help of perlbug 1.40 running under perl 5.25.1.

-----------------------------------------------------------------
[Please describe your issue here]

Only managed to narrow it happening between 5.20.0 and 5.21.10
somewhere
as all the perl's I have inbetween broke (libraries went away)

On 5.20.0, the following code is illegal and dies with "Cannot convert
a reference to HASH to typeglob at /tmp/wtf.pl line 13."

<--->
#!perl
use strict;
use warnings;

BEGIN {
my $namespace = do {
no strict 'refs';
\%{ 'Foo​::' };
};
$namespace->{bar} = { "key" => "value" };
}

print ref Foo​::bar() || 'nothing';

<--->

On 5.21.10+ , Foo​::bar() silently returns undef.

The changes in how subroutines are stored in stashes are probably responsible.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2016

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2016

From @cpansprout

On Sat Jun 25 07​:13​:49 2016, sprout wrote​:

The changes in how subroutines are stored in stashes are probably
responsible.

No, they are not. It was​:

211a434 is the first bad commit
commit 211a434
Author​: Father Chrysostomos <sprout@​cpan.org>
Date​: Fri Aug 29 20​:18​:23 2014 -0700

  Avoid vivifying stuff when looking up barewords
 
  Till now, when a bareword was looked up to see whether it was a sub-
  routine, an rv2cv op was created (to allow PL_check hooks to override
  the process), which was then asked for its GV.
 
  Afterwards, the GV was downgraded back to nothing if possible.
 
  So a lot of the time a GV was autovivified and then discarded. This
  has been the case since f746176 (5.12).
 
  If we know there is a good chance that the rv2cv op is about to be
  deleted, we can avoid that by passing a flag to the new op.
 
  Also f746176 actually changed the behaviour by vivifying stashes
  that used not be vivified​:
 
  sub foo { print shift, "\n" }
  SUPER​::foo bar if 0;
  foo SUPER;
 
  Output in 5.10​:
 
  SUPER
 
  Output as of this commit​:
 
  SUPER
 
  Output in 5.12 to 5.21.3​:
 
  Can't locate object method "foo" via package "SUPER" at - line 3.

That was an optimisation and regression fix. In fact, it restored the 5.10 behaviour​:

$ perl5.12 -e 'BEGIN {$Foo​::{bar} = {}} Foo​::bar()'
Cannot convert a reference to HASH to typeglob at -e line 1.
$ perl5.10 -e 'BEGIN {$Foo​::{bar} = {}} warn defined Foo​::bar()'
Warning​: something's wrong at -e line 1.
$ perl5.8.7 -e 'BEGIN {$Foo​::{bar} = {}} Foo​::bar()'
Undefined subroutine &Foo​::bar called at -e line 1.

So this was not terribly consistent to begin with. :-)

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2016

From @cpansprout

On Sat Jun 25 07​:31​:51 2016, sprout wrote​:

$ perl5.12 -e 'BEGIN {$Foo​::{bar} = {}} Foo​::bar()'
Cannot convert a reference to HASH to typeglob at -e line 1.
$ perl5.10 -e 'BEGIN {$Foo​::{bar} = {}} warn defined Foo​::bar()'
Warning​: something's wrong at -e line 1.
$ perl5.8.7 -e 'BEGIN {$Foo​::{bar} = {}} Foo​::bar()'
Undefined subroutine &Foo​::bar called at -e line 1.

So this was not terribly consistent to begin with. :-)

Even more interesting is that the behaviour changes back if I add the ampersand​:

$ perl5.10 -e 'BEGIN {$Foo​::{bar} = {}} &Foo​::bar()'
Cannot convert a reference to HASH to typeglob at -e line 1.
$ perl5.12 -e 'BEGIN {$Foo​::{bar} = {}} &Foo​::bar()'
Cannot convert a reference to HASH to typeglob at -e line 1.
$ perl5.24.0 -e 'BEGIN {$Foo​::{bar} = {}} &Foo​::bar()'
Cannot convert a reference to HASH to typeglob at -e line 1.

(5.8.7 still gives ‘Undefined subroutine’.)

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jun 25, 2016

From @cpansprout

On Sat Jun 25 07​:31​:51 2016, sprout wrote​:

$ perl5.12 -e 'BEGIN {$Foo​::{bar} = {}} Foo​::bar()'
Cannot convert a reference to HASH to typeglob at -e line 1.
$ perl5.10 -e 'BEGIN {$Foo​::{bar} = {}} warn defined Foo​::bar()'
Warning​: something's wrong at -e line 1.
$ perl5.8.7 -e 'BEGIN {$Foo​::{bar} = {}} Foo​::bar()'
Undefined subroutine &Foo​::bar called at -e line 1.

So this was not terribly consistent to begin with. :-)

It’s being treated as a constant​:

$ ./perl -Ilib -MO=Concise -e 'BEGIN {$Foo​::{bar} = {}} Foo​::bar()'
3 <@​> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 3 -e​:1) v​:{ ->3
- <0> ex-const v*/FOLD ->3
-e syntax OK

BTW, perlmod says​:

The results of creating new symbol table entries directly or modifying any
entries that are not already typeglobs are undefined and subject to change
between releases of perl.

So this is technically not a bug. :-)

--

Father Chrysostomos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants