@@ -511,10 +511,11 @@ Perl_grok_bin_oct_hex(pTHX_ const char * const start,
511511 * because a bit got shifted off the left end, so overflowed.
512512 * But if it worked, add the new digit. */
513513 if (LIKELY ((tentative_value >> shift ) == value )) {
514+ /* Note XDIGIT_VALUE() is branchless, works on binary and
515+ * octal as well, so can be used here, without noticeably
516+ * slowing those down (it does have unnecessary shifts, ANDSs,
517+ * and additions for those) */
514518 value = tentative_value | XDIGIT_VALUE (* s );
515- /* Note XDIGIT_VALUE() is branchless, works on binary
516- * and octal as well, so can be used here, without
517- * slowing those down */
518519 factor *= base ;
519520 continue ;
520521 }
@@ -551,14 +552,13 @@ Perl_grok_bin_oct_hex(pTHX_ const char * const start,
551552 continue ;
552553 }
553554
555+ /* Handle non-trailing underscores when those are accepted */
554556 if ( UNLIKELY (* s == '_' )
555557 && s < e - 1
556558 && allow_underscores
557559 && generic_isCC_ (s [1 ], class_bit )
558-
559- /* Don't allow a leading underscore if the only-medial bit is
560- * set */
561560 && ( LIKELY (s > s0 )
561+ /* Including initial underscores if those are accepted */
562562 || UNLIKELY (! ( input_flags
563563 & PERL_SCAN_ALLOW_MEDIAL_UNDERSCORES_ONLY ))))
564564 {
@@ -575,6 +575,9 @@ Perl_grok_bin_oct_hex(pTHX_ const char * const start,
575575 }
576576 }
577577
578+ /* We get here when done with the parse, or it got interrupted by a
579+ * non-digit or a digit that is outside the bounds of the base, like a
580+ * digit 2 in a binary number */
578581 if (* s ) {
579582 if ( ! (input_flags & PERL_SCAN_SILENT_ILLDIGIT )
580583 && ckWARN (WARN_DIGIT ))
@@ -593,7 +596,8 @@ Perl_grok_bin_oct_hex(pTHX_ const char * const start,
593596 * scanning as soon as non-octal characters are seen,
594597 * complain only if someone seems to want to use the digits
595598 * eight and nine. Since we know it is not octal, then if
596- * isDIGIT, must be an 8 or 9). */
599+ * isDIGIT, must be an 8 or 9). khw: XXX why not DWIM for
600+ * other bases as well? */
597601 warner (packWARN (WARN_DIGIT ),
598602 "Illegal octal digit '%c' ignored" , * s );
599603 }
@@ -604,8 +608,9 @@ Perl_grok_bin_oct_hex(pTHX_ const char * const start,
604608 }
605609 }
606610
611+ /* Error, so quit parsing */
607612 break ;
608- }
613+ } /* End of parsing loop */
609614
610615 * len_p = s - start ;
611616
0 commit comments