This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix handling of registered warning categories
authorZefram <zefram@fysh.org>
Wed, 15 Nov 2017 17:41:29 +0000 (17:41 +0000)
committerZefram <zefram@fysh.org>
Wed, 15 Nov 2017 18:25:56 +0000 (18:25 +0000)
commit006c1a1dbd541b84351332b0d315508f789f3bd1
tree9f2c8cdfb793d0f00d223584d9af5f395b11cd96
parentf019f33b79ce6bf1ffc1ef457eba44074b721ead
fix handling of registered warning categories

There were some problems arising from some warning bitsets being shorter
than others, which happens when registration of a new warning category
makes new bitsets longer.  Most obviously, if a scope used "use warnings
'all'" to turn on all warnings and then turned off some specific warnings,
then that scope wouldn't get warnings for subsequently-registered warning
categories, because its bitset doesn't extend to the bit controlling
the new category.  (If just "use warnings 'all'" was used, without any
customisation, then a special hack made that work for new categories.)
It was also possible for a longer bitset to get truncated by a warnings
pragma, because the bitset editing code assumed that all bitsets are
the same length.

To fix this, first the warning bits for the "all" category have to change
meaning.  Unlike all other warning categories, the bits for "all" used to
be set only when there were no warning categories disabled; disabling any
would also clear the "all" bits.  That was supporting the special hack
mentioned above that the all-warnings bitset work for new categories.
This exception is now removed, so the meaning of the "all" bits is now the
more obvious meaning, of indicating the default treatment that the scope
wants for warnings not falling into any category known to the bitset.
In warnings::warnif() et al, if the caller's bitset is found to be too
short to have a bit for the relevant category, then the setting for the
"all" category is used instead.

Because the length of a bitset is an integral number of bytes, but
only two bits are used per category, the length of a bitset doesn't
precisely indicate which categories had been registered by the time it
was constructed.  So the standard bitsets for the "all" category are
now always filled to their byte length, with bits set preemptively for
categories not yet registered that fall within the current bitset length.

When a warnings pragma operates on a bitset, it first expands it to the
preferred length, by duplicating the "all" bits for the categories covered
by the new length.  It is careful to maintain the length when combining
the bitset with the standard bitsets for categories.  When a bitset is
read from ${^WARNING_BITS} or from caller(), the standard pWARN_ALL
setting is no longer expanded by the core to $warnings::Bits{all},
because the core's short WARN_ALLstring will now be expanded correctly
just like any other bitset.

Fixes [perl #108778].
lib/B/Deparse.t
lib/warnings.pm
mg.c
pp_ctl.c
regen/warnings.pl
t/lib/warnings/9enabled
t/op/caller.t
warnings.h