Blame SOURCES/perl-5.30.1-perl-125557-correctly-handle-overload-for-bin-oct-fl.patch

7586d2
From b061e315b4eac4d82edb3ca14581805417a68936 Mon Sep 17 00:00:00 2001
7586d2
From: Tony Cook <tony@develop-help.com>
7586d2
Date: Wed, 11 Sep 2019 11:50:23 +1000
7586d2
Subject: [PATCH] (perl #125557) correctly handle overload for bin/oct floats
7586d2
MIME-Version: 1.0
7586d2
Content-Type: text/plain; charset=UTF-8
7586d2
Content-Transfer-Encoding: 8bit
7586d2
7586d2
The hexfp code doesn't check that the shift is 4, and so also
7586d2
accepts binary and octal fp numbers.
7586d2
7586d2
Unfortunately the call to S_new_constant() always passed a prefix
7586d2
of 0x, so overloading would be trying to parse the wrong number.
7586d2
7586d2
Another option is to simply allow only hex floats, though some work
7586d2
was done in 131894 to improve oct/bin float support.
7586d2
7586d2
Petr Písař: Ported to 5.30.1 from
7586d2
2cb5a7e8af11acb0eca22421ec5a4df7ef18e2a9.
7586d2
7586d2
Signed-off-by: Petr Písař <ppisar@redhat.com>
7586d2
---
7586d2
 t/op/hexfp.t | 16 +++++++++++++++-
7586d2
 toke.c       | 21 ++++++++++++++++-----
7586d2
 2 files changed, 31 insertions(+), 6 deletions(-)
7586d2
7586d2
diff --git a/t/op/hexfp.t b/t/op/hexfp.t
7586d2
index 64f8136..0f239d4 100644
7586d2
--- a/t/op/hexfp.t
7586d2
+++ b/t/op/hexfp.t
7586d2
@@ -10,7 +10,7 @@ use strict;
7586d2
 
7586d2
 use Config;
7586d2
 
7586d2
-plan(tests => 123);
7586d2
+plan(tests => 125);
7586d2
 
7586d2
 # Test hexfloat literals.
7586d2
 
7586d2
@@ -277,6 +277,20 @@ is(0b1p0, 1);
7586d2
 is(0b10p0, 2);
7586d2
 is(0b1.1p0, 1.5);
7586d2
 
7586d2
+# previously these would pass "0x..." to the overload instead of the appropriate
7586d2
+# "0b" or "0" prefix.
7586d2
+fresh_perl_is(<<'CODE', "1", {}, "overload binary fp");
7586d2
+use overload;
7586d2
+BEGIN { overload::constant float => sub { return eval $_[0]; }; }
7586d2
+print 0b0.1p1;
7586d2
+CODE
7586d2
+
7586d2
+fresh_perl_is(<<'CODE', "1", {}, "overload octal fp");
7586d2
+use overload;
7586d2
+BEGIN { overload::constant float => sub { return eval $_[0]; }; }
7586d2
+print 00.1p3;
7586d2
+CODE
7586d2
+
7586d2
 # sprintf %a/%A testing is done in sprintf2.t,
7586d2
 # trickier than necessary because of long doubles,
7586d2
 # and because looseness of the spec.
7586d2
diff --git a/toke.c b/toke.c
7586d2
index 03c4f2b..3fa20dc 100644
7586d2
--- a/toke.c
7586d2
+++ b/toke.c
7586d2
@@ -10966,6 +10966,7 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
7586d2
     const char *lastub = NULL;		/* position of last underbar */
7586d2
     static const char* const number_too_long = "Number too long";
7586d2
     bool warned_about_underscore = 0;
7586d2
+    I32 shift; /* shift per digit for hex/oct/bin, hoisted here for fp */
7586d2
 #define WARN_ABOUT_UNDERSCORE() \
7586d2
 	do { \
7586d2
 	    if (!warned_about_underscore) { \
7586d2
@@ -11012,8 +11013,6 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
7586d2
 	{
7586d2
 	  /* variables:
7586d2
 	     u		holds the "number so far"
7586d2
-	     shift	the power of 2 of the base
7586d2
-			(hex == 4, octal == 3, binary == 1)
7586d2
 	     overflowed	was the number more than we can hold?
7586d2
 
7586d2
 	     Shift is used when we add a digit.  It also serves as an "are
7586d2
@@ -11022,7 +11021,6 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
7586d2
 	   */
7586d2
 	    NV n = 0.0;
7586d2
 	    UV u = 0;
7586d2
-	    I32 shift;
7586d2
 	    bool overflowed = FALSE;
7586d2
 	    bool just_zero  = TRUE;	/* just plain 0 or binary number? */
7586d2
 	    static const NV nvshift[5] = { 1.0, 2.0, 4.0, 8.0, 16.0 };
7586d2
@@ -11369,8 +11367,21 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
7586d2
         if (hexfp) {
7586d2
             floatit = TRUE;
7586d2
             *d++ = '0';
7586d2
-            *d++ = 'x';
7586d2
-            s = start + 2;
7586d2
+            switch (shift) {
7586d2
+            case 4:
7586d2
+                *d++ = 'x';
7586d2
+                s = start + 2;
7586d2
+                break;
7586d2
+            case 3:
7586d2
+                s = start + 1;
7586d2
+                break;
7586d2
+            case 1:
7586d2
+                *d++ = 'b';
7586d2
+                s = start + 2;
7586d2
+                break;
7586d2
+            default:
7586d2
+                NOT_REACHED; /* NOTREACHED */
7586d2
+            }
7586d2
         }
7586d2
 
7586d2
 	/* read next group of digits and _ and copy into d */
7586d2
-- 
7586d2
2.21.0
7586d2