summaryrefslogtreecommitdiff
path: root/regen
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2021-10-07 17:15:47 +0100
committerDavid Mitchell <davem@iabyn.com>2021-10-07 17:31:33 +0100
commit07a6208729c01c230010594c3e08a946ab0ccbef (patch)
treec22730559b0cda43ef9ea337f896c6aeb0f2eb1e /regen
parent2b0c7afada71b2d42dd50ec342a0e9878e4e2ef2 (diff)
downloadperl-07a6208729c01c230010594c3e08a946ab0ccbef.tar.gz
add OPpUSEINT op_private flag bit
The bitwise ops, such as a '<<', have an op_private flag that is set when compiled within the scope of 'use integer;'. Unfortunately, due to historical reasons, the defined flag that indicates this bit (bit 0) is HINT_INTEGER rather than an OPpfoo define. But HINT_INTEGER is supposed to represent a bit within PL_hints, not a bit within op_private. If someone reorganised the flags in PL_hints at some point, it would mess up bitwise ops. So this commit: 1) adds a new flag, OPpUSEINT, to indicate the bit within op_private. 2) Changes this flag's value from 0x1 to 0x4 to force it to be different than HINT_INTEGER - thus potentially flushing out any misuse of this flag anywhere (in core or XS code). 3) tells regen/op_private that the lower two bits of op_private in bitwise ops don't contain the argument count. They never did, but not specifying that in regen/op_private meant that the debugging code in op_free() never spotted the unknown bit 0 sometimes being set. 4) Also tell that debugging code to skip the test if the op is banned. This fixes a new fail in dist/Safe/t/safeops.t which was croaking about a banned op having an unrecognised op_private flag bit set before ck_bitop() had a chance to delete the arg count in op_private.
Diffstat (limited to 'regen')
-rw-r--r--regen/op_private17
1 files changed, 17 insertions, 0 deletions
diff --git a/regen/op_private b/regen/op_private
index ea24474308..357b4a1a32 100644
--- a/regen/op_private
+++ b/regen/op_private
@@ -201,6 +201,13 @@ use strict;
$args0{$_} = 1 for qw(entersub avhvswitch
rv2hv); # UNOPs that usurp bit 0
+ # Historically, bit ops used bit 0 to indicate 'use integer' in scope;
+ # For now, ban use of bits 0..1 as an arg count, in order to detect
+ # any residual code which conflates use of the HINT_INTEGER and
+ # OPpUSEINT flags
+
+ $args0{$_} = 1 for ops_with_check('ck_bitop');
+
$args1{$_} = 1 for (
qw(reverse), # ck_fun(), but most bits stolen
qw(mapstart grepstart), # set in ck_fun, but
@@ -281,6 +288,16 @@ use strict;
}
+# Are these bit ops in the scope of 'use integer'?
+#
+# Note that historically they used to use bit 0, which corresponded to
+# HINT_INTEGER (a bit flags within PL_hints). We deliberately choose
+# a value (2) different than that flag, and different to the two bits used
+# to store the argument count, to flush out any residual code which
+# conflates the two.
+
+addbits($_, 2 => qw(OPpUSEINT USEINT))
+ for ops_with_check('ck_bitop');
# if NATIVE_HINTS is defined, op_private on cops holds the top 8 bits
# of PL_hints, although only bits 6 & 7 are officially used for that