summaryrefslogtreecommitdiff
path: root/op.c
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 /op.c
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 'op.c')
-rw-r--r--op.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/op.c b/op.c
index c7ee2c1a4c..d015c390d9 100644
--- a/op.c
+++ b/op.c
@@ -946,11 +946,15 @@ Perl_op_free(pTHX_ OP *o)
* inconsistent state then. Note that an error when
* compiling the main program leaves PL_parser NULL, so
* we can't spot faults in the main code, only
- * evaled/required code */
+ * evaled/required code;
+ * * it's a banned op - we may be croaking before the op is
+ * fully formed. - see CHECKOP. */
#ifdef DEBUGGING
if ( o->op_ppaddr == PL_ppaddr[type]
&& PL_parser
- && !PL_parser->error_count)
+ && !PL_parser->error_count
+ && !(PL_op_mask && PL_op_mask[type])
+ )
{
assert(!(o->op_private & ~PL_op_private_valid[type]));
}
@@ -12569,7 +12573,8 @@ Perl_ck_bitop(pTHX_ OP *o)
{
PERL_ARGS_ASSERT_CK_BITOP;
- o->op_private = (U8)(PL_hints & HINT_INTEGER);
+ /* get rid of arg count and indicate if in the scope of 'use integer' */
+ o->op_private = (PL_hints & HINT_INTEGER) ? OPpUSEINT : 0;
if (!(o->op_flags & OPf_STACKED) /* Not an assignment */
&& OP_IS_INFIX_BIT(o->op_type))