public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r14-8937] libiberty: Fix up libiberty_vprintf_buffer_size
Date: Mon, 12 Feb 2024 17:52:32 +0000 (GMT)	[thread overview]
Message-ID: <20240212175232.7EB543858CDB@sourceware.org> (raw)

https://gcc.gnu.org/g:53bb7145135c0c9fe7f9735231befe2c7cba2708

commit r14-8937-g53bb7145135c0c9fe7f9735231befe2c7cba2708
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Mon Feb 12 18:50:16 2024 +0100

    libiberty: Fix up libiberty_vprintf_buffer_size
    
    When writing the HOST_SIZE_T_PRINT_UNSIGNED incremental patch,
    my first bootstrap failed on i686-linux.  That is because I've also had
    @@ -1344,8 +1344,10 @@ adjust_field_rtx_def (type_p t, options_
                }
    
              subfields = create_field (subfields, t,
    -                                   xasprintf (".fld[%lu].%s",
    -                                              (unsigned long) aindex,
    +                                   xasprintf (".fld["
    +                                              HOST_SIZE_T_PRINT_UNSIGNED
    +                                              "].%s",
    +                                              (fmt_size_t) aindex,
                                                   subname));
              subfields->opt = nodot;
              if (t == note_union_tp)
    hunk in gengtype.cc.  While sprintf obviously can print in this case %llu
    with fmt_size_t being unsigned long long (that is another bug I'll fix
    incrementally), seems libiberty_vprintf_buffer_size
    can't deal with that, it ignores h, hh, l, ll and L modifiers and
    unconditionally, estimates 30 chars as upper bounds for integers (that is
    fine) and then uses (void) va_arg (ap, int); to skip over the argument
    regardless if it was %d, %ld, %lld, %hd, %hhd etc.
    Now, on x86_64 that happens to work fine probably for all of those,
    on ia32 for everything but %lld, because it then skips just one half
    of the long long argument; now as there is %s after it, it will try to
    compute strlen not from the pointer argument corresponding to %s, but
    from the most significant half of the previous long long argument.
    
    So, the following patch attempts not to completely ignore the modifiers,
    but figure out from them whether to va_arg an int (used for h and hh as
    well), or long, or long long, or size_t, or ptrdiff_t - added support for
    z and t there, plus for Windows I64.  And also %Lf etc. for long double.
    
    2024-02-12  Jakub Jelinek  <jakub@redhat.com>
    
            * vprintf-support.c (libiberty_vprintf_buffer_size): Handle
            properly l, ll, z, t or on _WIN32 I64 modifiers for diouxX
            and L modifier for fFgGeE.

Diff:
---
 libiberty/vprintf-support.c | 65 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 6 deletions(-)

diff --git a/libiberty/vprintf-support.c b/libiberty/vprintf-support.c
index b590e5ab034e..0543ec0554ec 100644
--- a/libiberty/vprintf-support.c
+++ b/libiberty/vprintf-support.c
@@ -56,6 +56,7 @@ libiberty_vprintf_buffer_size (const char *format, va_list args)
     {
       if (*p++ == '%')
 	{
+	  int prec = 0;
 	  while (strchr ("-+ #0", *p))
 	    ++p;
 	  if (*p == '*')
@@ -76,8 +77,43 @@ libiberty_vprintf_buffer_size (const char *format, va_list args)
 	      else
 	      total_width += strtoul (p, (char **) &p, 10);
 	    }
-	  while (strchr ("hlL", *p))
-	    ++p;
+	  do
+	    {
+	      switch (*p)
+		{
+		case 'h':
+		  ++p;
+		  continue;
+		case 'l':
+		case 'L':
+		  ++prec;
+		  ++p;
+		  continue;
+		case 'z':
+		  prec = 3;
+		  ++p;
+		  continue;
+		case 't':
+		  prec = 4;
+		  ++p;
+		  continue;
+#ifdef _WIN32
+		case 'I':
+		  if (p[1] == '6' && p[2] == '4')
+		    {
+		      prec = 2;
+		      p += 3;
+		      continue;
+		    }
+		  break;
+#endif
+		default:
+		  break;
+		}
+	      break;
+	    }
+	  while (1);
+
 	  /* Should be big enough for any format specifier except %s and floats.  */
 	  total_width += 30;
 	  switch (*p)
@@ -88,6 +124,15 @@ libiberty_vprintf_buffer_size (const char *format, va_list args)
 	    case 'u':
 	    case 'x':
 	    case 'X':
+	      switch (prec)
+		{
+		case 0: (void) va_arg (ap, int); break;
+		case 1: (void) va_arg (ap, long int); break;
+		case 2: (void) va_arg (ap, long long int); break;
+		case 3: (void) va_arg (ap, size_t); break;
+		case 4: (void) va_arg (ap, ptrdiff_t); break;
+		}
+	      break;
 	    case 'c':
 	      (void) va_arg (ap, int);
 	      break;
@@ -96,10 +141,18 @@ libiberty_vprintf_buffer_size (const char *format, va_list args)
 	    case 'E':
 	    case 'g':
 	    case 'G':
-	      (void) va_arg (ap, double);
-	      /* Since an ieee double can have an exponent of 307, we'll
-		 make the buffer wide enough to cover the gross case. */
-	      total_width += 307;
+	      if (!prec)
+		{
+		  (void) va_arg (ap, double);
+		  /* Since an ieee double can have an exponent of 308, we'll
+		     make the buffer wide enough to cover the gross case. */
+		  total_width += 308;
+		}
+	      else
+		{
+		  (void) va_arg (ap, long double);
+		  total_width += 4932;
+		}
 	      break;
 	    case 's':
 	      total_width += strlen (va_arg (ap, char *));

                 reply	other threads:[~2024-02-12 17:52 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240212175232.7EB543858CDB@sourceware.org \
    --to=jakub@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).