diff options
author | Jan Beulich <jbeulich@suse.com> | 2021-06-16 08:55:52 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2021-06-16 08:55:52 +0200 |
commit | bb32eac5a90b2b141fed4ce490aded74134f1d75 (patch) | |
tree | 9c3a5e48cee0a436229e28481ce896ca3c10d109 | |
parent | 4504a6346777d544a144683bd2a534b686fbac41 (diff) | |
download | fsf-binutils-gdb-bb32eac5a90b2b141fed4ce490aded74134f1d75.zip fsf-binutils-gdb-bb32eac5a90b2b141fed4ce490aded74134f1d75.tar.gz fsf-binutils-gdb-bb32eac5a90b2b141fed4ce490aded74134f1d75.tar.bz2 |
gas: fix hex float parsing from .dcb.? directives
Unlike for .dc.? the parsing here failed to skip the colon before
calling hex_float(). To avoid both variants of parsing going out of sync
again, introduce a helper used by both.
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/read.c | 124 | ||||
-rw-r--r-- | gas/testsuite/gas/all/float.s | 16 |
3 files changed, 75 insertions, 71 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index ebbf27f..8fa1be8 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,11 @@ 2021-06-16 Jan Beulich <jbeulich@suse.com> + * read.c (parse_one_float): New. + (s_float_space, float_cons): Use it. + * testsuite/gas/all/float.s: Add .dc.*, .dcb.*, and .ds.* cases. + +2021-06-16 Jan Beulich <jbeulich@suse.com> + * read.c (emit_expr_with_reloc): Adjust overflow check. Drop hibit local variable. * write.c (fixup_segment): Differentiate signed and non-signed @@ -3616,6 +3616,51 @@ s_nops (int ignore ATTRIBUTE_UNUSED) *p = val.X_add_number; } +static int +parse_one_float (int float_type, char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT]) +{ + int length; + + SKIP_WHITESPACE (); + + /* Skip any 0{letter} that may be present. Don't even check if the + letter is legal. Someone may invent a "z" format and this routine + has no use for such information. Lusers beware: you get + diagnostics if your input is ill-conditioned. */ + if (input_line_pointer[0] == '0' + && ISALPHA (input_line_pointer[1])) + input_line_pointer += 2; + + /* Accept :xxxx, where the x's are hex digits, for a floating point + with the exact digits specified. */ + if (input_line_pointer[0] == ':') + { + ++input_line_pointer; + length = hex_float (float_type, temp); + if (length < 0) + { + ignore_rest_of_line (); + return length; + } + } + else + { + const char *err; + + err = md_atof (float_type, temp, &length); + know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); + know (err != NULL || length > 0); + if (err) + { + as_bad (_("bad floating literal: %s"), err); + ignore_rest_of_line (); + return -1; + } + } + + return length; +} + /* This is like s_space, but the value is a floating point number with the given precision. This is for the MRI dcb.s pseudo-op and friends. */ @@ -3650,42 +3695,12 @@ s_float_space (int float_type) ++input_line_pointer; - SKIP_WHITESPACE (); - - /* Skip any 0{letter} that may be present. Don't even check if the - * letter is legal. */ - if (input_line_pointer[0] == '0' - && ISALPHA (input_line_pointer[1])) - input_line_pointer += 2; - - /* Accept :xxxx, where the x's are hex digits, for a floating point - with the exact digits specified. */ - if (input_line_pointer[0] == ':') - { - flen = hex_float (float_type, temp); - if (flen < 0) - { - ignore_rest_of_line (); - if (flag_mri) - mri_comment_end (stop, stopc); - return; - } - } - else + flen = parse_one_float (float_type, temp); + if (flen < 0) { - const char *err; - - err = md_atof (float_type, temp, &flen); - know (flen <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); - know (err != NULL || flen > 0); - if (err) - { - as_bad (_("bad floating literal: %s"), err); - ignore_rest_of_line (); - if (flag_mri) - mri_comment_end (stop, stopc); - return; - } + if (flag_mri) + mri_comment_end (stop, stopc); + return; } while (--count >= 0) @@ -4909,7 +4924,6 @@ float_cons (/* Clobbers input_line-pointer, checks end-of-line. */ { char *p; int length; /* Number of chars in an object. */ - const char *err; /* Error from scanning floating literal. */ char temp[MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT]; if (is_it_end_of_statement ()) @@ -4943,41 +4957,9 @@ float_cons (/* Clobbers input_line-pointer, checks end-of-line. */ do { - /* input_line_pointer->1st char of a flonum (we hope!). */ - SKIP_WHITESPACE (); - - /* Skip any 0{letter} that may be present. Don't even check if the - letter is legal. Someone may invent a "z" format and this routine - has no use for such information. Lusers beware: you get - diagnostics if your input is ill-conditioned. */ - if (input_line_pointer[0] == '0' - && ISALPHA (input_line_pointer[1])) - input_line_pointer += 2; - - /* Accept :xxxx, where the x's are hex digits, for a floating - point with the exact digits specified. */ - if (input_line_pointer[0] == ':') - { - ++input_line_pointer; - length = hex_float (float_type, temp); - if (length < 0) - { - ignore_rest_of_line (); - return; - } - } - else - { - err = md_atof (float_type, temp, &length); - know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT); - know (err != NULL || length > 0); - if (err) - { - as_bad (_("bad floating literal: %s"), err); - ignore_rest_of_line (); - return; - } - } + length = parse_one_float (float_type, temp); + if (length < 0) + return; if (!need_pass_2) { diff --git a/gas/testsuite/gas/all/float.s b/gas/testsuite/gas/all/float.s index 902914f..579ca89 100644 --- a/gas/testsuite/gas/all/float.s +++ b/gas/testsuite/gas/all/float.s @@ -4,3 +4,19 @@ foo: .single 0r1.2345e+06 .double 0r2.718282 .double .0000000000000000000001 .double 1e-22 + + .dc.s 1 + .dc.s 0f:1234 + .dcb.s 1, 1 + .dcb.s 1, 0s:4321 + .ds.s 1, -1 + + .dc.d 1 + .dc.d 0d:1234 + .dcb.d 1, 1 + .dcb.d 1, 0r:4321 + .ds.d 1, -1 + + .dc.x 0x:1234 + .dcb.x 1, 0x:4321 + .ds.x 1, -1 |