Re: -Wformat-overflow handling for %b and %B directives in C2X standard

2022-11-28 Thread Jeff Law via Gcc-patches




On 9/1/22 03:41, Даниил Александрович Фролов via Gcc-patches wrote:

Subject:
Re: -Wformat-overflow handling for %b and %B directives in C2X standard
From:
Даниил Александрович Фролов via Gcc-patches 
Date:
9/1/22, 03:41

To:
Marek Polacek 
CC:
"gcc-patches@gcc.gnu.org" 


 From eb9e8241d99145020ec5c050c918c1ad3abc2701 Mon Sep 17 00:00:00 2001
From: Frolov Daniil
Date: Thu, 1 Sep 2022 10:55:01 +0300
Subject: [PATCH] Support %b, %B for -Wformat-overflow (sprintf, snprintf)

gcc/ChangeLog:

* gimple-ssa-sprintf.cc (fmtresult::type_max_digits): Handle
base == 2.
(tree_digits): Likewise.
(format_integer): Likewise.
(parse_directive): Add cases for %b and %B directives.

gcc/testsuite/ChangeLog:

* gcc.dg/Wformat-overflow1.c: New test.

Thanks.  I've pushed this to the trunk.

Jeff


Re: -Wformat-overflow handling for %b and %B directives in C2X standard

2022-09-01 Thread Даниил Александрович Фролов via Gcc-patches
From eb9e8241d99145020ec5c050c918c1ad3abc2701 Mon Sep 17 00:00:00 2001
From: Frolov Daniil 
Date: Thu, 1 Sep 2022 10:55:01 +0300
Subject: [PATCH] Support %b, %B for -Wformat-overflow (sprintf, snprintf)

gcc/ChangeLog:

	* gimple-ssa-sprintf.cc (fmtresult::type_max_digits): Handle
	base == 2.
	(tree_digits): Likewise.
	(format_integer): Likewise.
	(parse_directive): Add cases for %b and %B directives.

gcc/testsuite/ChangeLog:

	* gcc.dg/Wformat-overflow1.c: New test.
---
 gcc/gimple-ssa-sprintf.cc| 41 +++-
 gcc/testsuite/gcc.dg/Wformat-overflow1.c | 28 
 2 files changed, 53 insertions(+), 16 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/Wformat-overflow1.c

diff --git a/gcc/gimple-ssa-sprintf.cc b/gcc/gimple-ssa-sprintf.cc
index a888b5ac7d5..1dd9b0dc46b 100644
--- a/gcc/gimple-ssa-sprintf.cc
+++ b/gcc/gimple-ssa-sprintf.cc
@@ -535,6 +535,8 @@ fmtresult::type_max_digits (tree type, int base)
   unsigned prec = TYPE_PRECISION (type);
   switch (base)
 {
+case 2:
+  return prec;
 case 8:
   return (prec + 2) / 3;
 case 10:
@@ -804,9 +806,9 @@ ilog (unsigned HOST_WIDE_INT x, int base)
 /* Return the number of bytes resulting from converting into a string
the INTEGER_CST tree node X in BASE with a minimum of PREC digits.
PLUS indicates whether 1 for a plus sign should be added for positive
-   numbers, and PREFIX whether the length of an octal ('O') or hexadecimal
-   ('0x') prefix should be added for nonzero numbers.  Return -1 if X cannot
-   be represented.  */
+   numbers, and PREFIX whether the length of an octal ('0') or hexadecimal
+   ('0x') or binary ('0b') prefix should be added for nonzero numbers.
+   Return -1 if X cannot be represented.  */
 
 static HOST_WIDE_INT
 tree_digits (tree x, int base, HOST_WIDE_INT prec, bool plus, bool prefix)
@@ -857,11 +859,11 @@ tree_digits (tree x, int base, HOST_WIDE_INT prec, bool plus, bool prefix)
 
   /* Adjust a non-zero value for the base prefix, either hexadecimal,
  or, unless precision has resulted in a leading zero, also octal.  */
-  if (prefix && absval && (base == 16 || prec <= ndigs))
+  if (prefix && absval)
 {
-  if (base == 8)
+  if (base == 8 && prec <= ndigs)
 	res += 1;
-  else if (base == 16)
+  else if (base == 16 || base == 2) /* 0x...(0X...) or 0b...(0B...).  */
 	res += 2;
 }
 
@@ -1209,7 +1211,7 @@ format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
 
   /* True when a conversion is preceded by a prefix indicating the base
  of the argument (octal or hexadecimal).  */
-  bool maybebase = dir.get_flag ('#');
+  const bool maybebase = dir.get_flag ('#');
 
   /* True when a signed conversion is preceded by a sign or space.  */
   bool maybesign = false;
@@ -1229,6 +1231,10 @@ format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
 case 'u':
   base = 10;
   break;
+case 'b':
+case 'B':
+  base = 2;
+  break;
 case 'o':
   base = 8;
   break;
@@ -1240,6 +1246,8 @@ format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
   gcc_unreachable ();
 }
 
+  const unsigned adj = (sign | maybebase) + (base == 2 || base == 16);
+
   /* The type of the "formal" argument expected by the directive.  */
   tree dirtype = NULL_TREE;
 
@@ -1350,11 +1358,9 @@ format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
   res.range.unlikely = res.range.max;
 
   /* Bump up the counters if WIDTH is greater than LEN.  */
-  res.adjust_for_width_or_precision (dir.width, dirtype, base,
-	 (sign | maybebase) + (base == 16));
+  res.adjust_for_width_or_precision (dir.width, dirtype, base, adj);
   /* Bump up the counters again if PRECision is greater still.  */
-  res.adjust_for_width_or_precision (dir.prec, dirtype, base,
-	 (sign | maybebase) + (base == 16));
+  res.adjust_for_width_or_precision (dir.prec, dirtype, base, adj);
 
   return res;
 }
@@ -1503,17 +1509,15 @@ format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
 	  if (res.range.min == 1)
 	res.range.likely += base == 8 ? 1 : 2;
 	  else if (res.range.min == 2
-		   && base == 16
+		   && (base == 16 || base == 2)
 		   && (dir.width[0] == 2 || dir.prec[0] == 2))
 	++res.range.likely;
 	}
 }
 
   res.range.unlikely = res.range.max;
-  res.adjust_for_width_or_precision (dir.width, dirtype, base,
- (sign | maybebase) + (base == 16));
-  res.adjust_for_width_or_precision (dir.prec, dirtype, base,
- (sign | maybebase) + (base == 16));
+  res.adjust_for_width_or_precision (dir.width, dirtype, base, adj);
+  res.adjust_for_width_or_precision (dir.prec, dirtype, base, adj);
 
   return res;
 }
@@ -3725,6 +3729,11 @@ parse_directive (call_info &info,
   dir.fmtfunc = format_integer;
   break;
 
+case 'b':
+case 'B':
+  dir.fmtfunc = format_integer;
+  break;
+

Re: -Wformat-overflow handling for %b and %B directives in C2X standard

2022-08-30 Thread Marek Polacek via Gcc-patches
On Mon, Aug 15, 2022 at 07:42:39PM +0300, Frolov Daniil wrote:
> вт, 12 апр. 2022 г. в 00:56, Marek Polacek :
> 
> >
> > On Thu, Apr 07, 2022 at 02:10:48AM +0500, Frolov Daniil wrote:
> > > Hello! Thanks for your feedback. I've tried to take into account your
> > > comments. New patch applied to the letter.
> >
> > Thanks.
> >
> > > The only thing I have not removed is the check_std_c2x () function. From 
> > > my
> > > point of view -Wformat-overflow shouldn't be thrown if the standard < C2X.
> > > So it's protection for false triggering.
> >
> > Sorry but I still think that is the wrong behavior.  If you want to warn
> > about C2X constructs in pre-C2X modes, use -Wpedantic.  But if you want
> > to use %b/%B as an extension in older dialects, that's OK too, so I don't
> > know why users would want -Wformat-overflow disabled in that case.  But
> > perhaps other people disagree with me.
> >
> Hi! Sorry for the late reply. If we want to look at it as on extension
> then I am agreed with you.
> Removed this function in new patch.

Thanks, the patch looks good to me (I have one comment though), but I can't
approve it.

> @@ -1229,6 +1231,10 @@ format_integer (const directive &dir, tree arg, 
> pointer_query &ptr_qry)
>  case 'u':
>base = 10;
>break;
> +case 'b':
> +case 'B':
> +  base = 2;
> +  break;
>  case 'o':
>base = 8;
>break;
> @@ -1348,13 +1354,12 @@ format_integer (const directive &dir, tree arg, 
> pointer_query &ptr_qry)
>   }
>  
>res.range.unlikely = res.range.max;
> +  unsigned adj = (sign | maybebase) + (base == 2 || base == 16);

We have this same line here and ...
  
>/* Bump up the counters if WIDTH is greater than LEN.  */
> -  res.adjust_for_width_or_precision (dir.width, dirtype, base,
> -  (sign | maybebase) + (base == 16));
> +  res.adjust_for_width_or_precision (dir.width, dirtype, base, adj);
>/* Bump up the counters again if PRECision is greater still.  */
> -  res.adjust_for_width_or_precision (dir.prec, dirtype, base,
> -  (sign | maybebase) + (base == 16));
> +  res.adjust_for_width_or_precision (dir.prec, dirtype, base, adj);
>  
>return res;
>  }
> @@ -1503,17 +1508,16 @@ format_integer (const directive &dir, tree arg, 
> pointer_query &ptr_qry)
> if (res.range.min == 1)
>   res.range.likely += base == 8 ? 1 : 2;
> else if (res.range.min == 2
> -&& base == 16
> +&& (base == 16 || base == 2)
>  && (dir.width[0] == 2 || dir.prec[0] == 2))
>   ++res.range.likely;
>   }
>  }
>  
> +  unsigned adj = (sign | maybebase) + (base == 2 || base == 16);

... here, but sign, maybebase, and base couldn't have changed meanwhile.

So can we compute 'adj' just once after we've determined the base and sign,
and make it const?  And I think that if 'maybebase' is never changed in the
function, it ought to be made const as well.

Thanks,

Marek



Re: -Wformat-overflow handling for %b and %B directives in C2X standard

2022-08-15 Thread Frolov Daniil via Gcc-patches
вт, 12 апр. 2022 г. в 00:56, Marek Polacek :

>
> On Thu, Apr 07, 2022 at 02:10:48AM +0500, Frolov Daniil wrote:
> > Hello! Thanks for your feedback. I've tried to take into account your
> > comments. New patch applied to the letter.
>
> Thanks.
>
> > The only thing I have not removed is the check_std_c2x () function. From my
> > point of view -Wformat-overflow shouldn't be thrown if the standard < C2X.
> > So it's protection for false triggering.
>
> Sorry but I still think that is the wrong behavior.  If you want to warn
> about C2X constructs in pre-C2X modes, use -Wpedantic.  But if you want
> to use %b/%B as an extension in older dialects, that's OK too, so I don't
> know why users would want -Wformat-overflow disabled in that case.  But
> perhaps other people disagree with me.
>
Hi! Sorry for the late reply. If we want to look at it as on extension
then I am agreed with you.
Removed this function in new patch.
> > сб, 2 апр. 2022 г. в 01:15, Marek Polacek :
> >
> > > On Sat, Apr 02, 2022 at 12:19:47AM +0500, Frolov Daniil via Gcc-patches
> > > wrote:
> > > > Hello, I've noticed that -Wformat-overflow doesn't handle %b and %B
> > > > directives in the sprintf function. I've added a relevant issue in
> > > bugzilla
> > > > (bug #105129).
> > > > I attach a patch with a possible solution to the letter.
> > >
> > > Thanks for the patch.  Support for C2X %b, %B formats is relatively new
> > > (Oct 2021) so it looks like gimple-ssa-sprintf.cc hasn't caught up.
> > >
> > > This is not a regression, so should probably wait till GCC 13.  Anyway...
> > >
> > > > From 2051344e9500651f6e94c44cbc7820715382b957 Mon Sep 17 00:00:00 2001
> > > > From: Frolov Daniil 
> > > > Date: Fri, 1 Apr 2022 00:47:03 +0500
> > > > Subject: [PATCH] Support %b, %B for -Wformat-overflow (sprintf, 
> > > > snprintf)
> > > >
> > > > testsuite: add tests to check -Wformat-overflow on %b.
> > > > Wformat-overflow1.c is compiled using -std=c2x so warning has to
> > > > be throwed
> > > >
> > > > Wformat-overflow2.c doesn't throw warnings cause c2x std isn't
> > > > used
> > > >
> > > > gcc/ChangeLog:
> > > >
> > > >   * gimple-ssa-sprintf.cc
> > > > (check_std_c2x): New function
> > > >   (fmtresult::type_max_digits): add base == 2 handling
> > > >   (tree_digits): add handle for base == 2
> > > >   (format_integer): now handle %b and %B using base = 2
> > > >   (parse_directive): add cases to handle %b and %B directives
> > > >   (compute_format_length): add handling for base = 2
> > >
> > > The descriptions should start with a capital letter and end with a period,
> > > like "Handle base == 2."
> > >
> > > > gcc/testsuite/ChangeLog:
> > > >
> > > >   * gcc.dg/Wformat-overflow1.c: New test. (using -std=c2x)
> > > >   * gcc.dg/Wformat-overflow2.c: New test. (-std=c11 no warning)
> > >
> > > You can just say "New test."
> > >
> > > > ---
> > > >  gcc/gimple-ssa-sprintf.cc| 42 
> > > >  gcc/testsuite/gcc.dg/Wformat-overflow1.c | 28 
> > > >  gcc/testsuite/gcc.dg/Wformat-overflow2.c | 16 +
> > > >  3 files changed, 79 insertions(+), 7 deletions(-)
> > > >  create mode 100644 gcc/testsuite/gcc.dg/Wformat-overflow1.c
> > > >  create mode 100644 gcc/testsuite/gcc.dg/Wformat-overflow2.c
> > > >
> > > > diff --git a/gcc/gimple-ssa-sprintf.cc b/gcc/gimple-ssa-sprintf.cc
> > > > index c93f12f90b5..7f68c2b6e51 100644
> > > > --- a/gcc/gimple-ssa-sprintf.cc
> > > > +++ b/gcc/gimple-ssa-sprintf.cc
> > > > @@ -107,6 +107,15 @@ namespace {
> > > >
> > > >  static int warn_level;
> > > >
> > > > +/* b_overflow_flag depends on the current standart when using gcc */
> > >
> > > "standard"
> > >
> > > /* Comments should be formatted like this.  */
> > >
> > > > +static bool b_overflow_flag;
> > > > +
> > > > +/* check is current standart version equals C2X*/
> > > > +static bool check_std_c2x ()
> > > > +{
> > > > +  return !strcmp (lang_hooks.name, "GNU C2X");
> > > > +}
> > >
> > > Is this really needed?  ISTM that this new checking shouldn't depend on
> > > -std=c2x.  If not using C2X, you only get a warning if -Wpedantic.  So
> > > I think you should remove b_overflow_flag.
> > >
> > > >  /* The minimum, maximum, likely, and unlikely maximum number of bytes
> > > > of output either a formatting function or an individual directive
> > > > can result in.  */
> > > > @@ -535,6 +544,8 @@ fmtresult::type_max_digits (tree type, int base)
> > > >unsigned prec = TYPE_PRECISION (type);
> > > >switch (base)
> > > >  {
> > > > +case 2:
> > > > +  return prec;
> > > >  case 8:
> > > >return (prec + 2) / 3;
> > > >  case 10:
> > > > @@ -857,11 +868,11 @@ tree_digits (tree x, int base, HOST_WIDE_INT prec,
> > > bool plus, bool prefix)
> > > >
> > > >/* Adjust a non-zero value for the base prefix, either hexadecimal,
> > > >   or, unless precision has resulted in a leading zero, also octal.
> > > */
> > > > -  if (pr

Re: -Wformat-overflow handling for %b and %B directives in C2X standard

2022-04-11 Thread Marek Polacek via Gcc-patches
On Thu, Apr 07, 2022 at 02:10:48AM +0500, Frolov Daniil wrote:
> Hello! Thanks for your feedback. I've tried to take into account your
> comments. New patch applied to the letter.

Thanks.
 
> The only thing I have not removed is the check_std_c2x () function. From my
> point of view -Wformat-overflow shouldn't be thrown if the standard < C2X.
> So it's protection for false triggering.

Sorry but I still think that is the wrong behavior.  If you want to warn
about C2X constructs in pre-C2X modes, use -Wpedantic.  But if you want
to use %b/%B as an extension in older dialects, that's OK too, so I don't
know why users would want -Wformat-overflow disabled in that case.  But
perhaps other people disagree with me.

> сб, 2 апр. 2022 г. в 01:15, Marek Polacek :
> 
> > On Sat, Apr 02, 2022 at 12:19:47AM +0500, Frolov Daniil via Gcc-patches
> > wrote:
> > > Hello, I've noticed that -Wformat-overflow doesn't handle %b and %B
> > > directives in the sprintf function. I've added a relevant issue in
> > bugzilla
> > > (bug #105129).
> > > I attach a patch with a possible solution to the letter.
> >
> > Thanks for the patch.  Support for C2X %b, %B formats is relatively new
> > (Oct 2021) so it looks like gimple-ssa-sprintf.cc hasn't caught up.
> >
> > This is not a regression, so should probably wait till GCC 13.  Anyway...
> >
> > > From 2051344e9500651f6e94c44cbc7820715382b957 Mon Sep 17 00:00:00 2001
> > > From: Frolov Daniil 
> > > Date: Fri, 1 Apr 2022 00:47:03 +0500
> > > Subject: [PATCH] Support %b, %B for -Wformat-overflow (sprintf, snprintf)
> > >
> > > testsuite: add tests to check -Wformat-overflow on %b.
> > > Wformat-overflow1.c is compiled using -std=c2x so warning has to
> > > be throwed
> > >
> > > Wformat-overflow2.c doesn't throw warnings cause c2x std isn't
> > > used
> > >
> > > gcc/ChangeLog:
> > >
> > >   * gimple-ssa-sprintf.cc
> > > (check_std_c2x): New function
> > >   (fmtresult::type_max_digits): add base == 2 handling
> > >   (tree_digits): add handle for base == 2
> > >   (format_integer): now handle %b and %B using base = 2
> > >   (parse_directive): add cases to handle %b and %B directives
> > >   (compute_format_length): add handling for base = 2
> >
> > The descriptions should start with a capital letter and end with a period,
> > like "Handle base == 2."
> >
> > > gcc/testsuite/ChangeLog:
> > >
> > >   * gcc.dg/Wformat-overflow1.c: New test. (using -std=c2x)
> > >   * gcc.dg/Wformat-overflow2.c: New test. (-std=c11 no warning)
> >
> > You can just say "New test."
> >
> > > ---
> > >  gcc/gimple-ssa-sprintf.cc| 42 
> > >  gcc/testsuite/gcc.dg/Wformat-overflow1.c | 28 
> > >  gcc/testsuite/gcc.dg/Wformat-overflow2.c | 16 +
> > >  3 files changed, 79 insertions(+), 7 deletions(-)
> > >  create mode 100644 gcc/testsuite/gcc.dg/Wformat-overflow1.c
> > >  create mode 100644 gcc/testsuite/gcc.dg/Wformat-overflow2.c
> > >
> > > diff --git a/gcc/gimple-ssa-sprintf.cc b/gcc/gimple-ssa-sprintf.cc
> > > index c93f12f90b5..7f68c2b6e51 100644
> > > --- a/gcc/gimple-ssa-sprintf.cc
> > > +++ b/gcc/gimple-ssa-sprintf.cc
> > > @@ -107,6 +107,15 @@ namespace {
> > >
> > >  static int warn_level;
> > >
> > > +/* b_overflow_flag depends on the current standart when using gcc */
> >
> > "standard"
> >
> > /* Comments should be formatted like this.  */
> >
> > > +static bool b_overflow_flag;
> > > +
> > > +/* check is current standart version equals C2X*/
> > > +static bool check_std_c2x ()
> > > +{
> > > +  return !strcmp (lang_hooks.name, "GNU C2X");
> > > +}
> >
> > Is this really needed?  ISTM that this new checking shouldn't depend on
> > -std=c2x.  If not using C2X, you only get a warning if -Wpedantic.  So
> > I think you should remove b_overflow_flag.
> >
> > >  /* The minimum, maximum, likely, and unlikely maximum number of bytes
> > > of output either a formatting function or an individual directive
> > > can result in.  */
> > > @@ -535,6 +544,8 @@ fmtresult::type_max_digits (tree type, int base)
> > >unsigned prec = TYPE_PRECISION (type);
> > >switch (base)
> > >  {
> > > +case 2:
> > > +  return prec;
> > >  case 8:
> > >return (prec + 2) / 3;
> > >  case 10:
> > > @@ -857,11 +868,11 @@ tree_digits (tree x, int base, HOST_WIDE_INT prec,
> > bool plus, bool prefix)
> > >
> > >/* Adjust a non-zero value for the base prefix, either hexadecimal,
> > >   or, unless precision has resulted in a leading zero, also octal.
> > */
> > > -  if (prefix && absval && (base == 16 || prec <= ndigs))
> > > +  if (prefix && absval && (base == 2 || base == 16 || prec <= ndigs))
> > >  {
> > >if (base == 8)
> > >   res += 1;
> > > -  else if (base == 16)
> > > +  else if (base == 16 || base == 2) /*0x...(0X...) and
> > 0b...(0B...)*/
> > >   res += 2;
> > >  }
> > >
> > > @@ -1229,6 +1240,10 @@ format_integer (const directive &dir, t

Re: -Wformat-overflow handling for %b and %B directives in C2X standard

2022-04-06 Thread Frolov Daniil via Gcc-patches
Hello! Thanks for your feedback. I've tried to take into account your
comments. New patch applied to the letter.

The only thing I have not removed is the check_std_c2x () function. From my
point of view -Wformat-overflow shouldn't be thrown if the standard < C2X.
So it's protection for false triggering.

сб, 2 апр. 2022 г. в 01:15, Marek Polacek :

> On Sat, Apr 02, 2022 at 12:19:47AM +0500, Frolov Daniil via Gcc-patches
> wrote:
> > Hello, I've noticed that -Wformat-overflow doesn't handle %b and %B
> > directives in the sprintf function. I've added a relevant issue in
> bugzilla
> > (bug #105129).
> > I attach a patch with a possible solution to the letter.
>
> Thanks for the patch.  Support for C2X %b, %B formats is relatively new
> (Oct 2021) so it looks like gimple-ssa-sprintf.cc hasn't caught up.
>
> This is not a regression, so should probably wait till GCC 13.  Anyway...
>
> > From 2051344e9500651f6e94c44cbc7820715382b957 Mon Sep 17 00:00:00 2001
> > From: Frolov Daniil 
> > Date: Fri, 1 Apr 2022 00:47:03 +0500
> > Subject: [PATCH] Support %b, %B for -Wformat-overflow (sprintf, snprintf)
> >
> > testsuite: add tests to check -Wformat-overflow on %b.
> > Wformat-overflow1.c is compiled using -std=c2x so warning has to
> > be throwed
> >
> > Wformat-overflow2.c doesn't throw warnings cause c2x std isn't
> > used
> >
> > gcc/ChangeLog:
> >
> >   * gimple-ssa-sprintf.cc
> > (check_std_c2x): New function
> >   (fmtresult::type_max_digits): add base == 2 handling
> >   (tree_digits): add handle for base == 2
> >   (format_integer): now handle %b and %B using base = 2
> >   (parse_directive): add cases to handle %b and %B directives
> >   (compute_format_length): add handling for base = 2
>
> The descriptions should start with a capital letter and end with a period,
> like "Handle base == 2."
>
> > gcc/testsuite/ChangeLog:
> >
> >   * gcc.dg/Wformat-overflow1.c: New test. (using -std=c2x)
> >   * gcc.dg/Wformat-overflow2.c: New test. (-std=c11 no warning)
>
> You can just say "New test."
>
> > ---
> >  gcc/gimple-ssa-sprintf.cc| 42 
> >  gcc/testsuite/gcc.dg/Wformat-overflow1.c | 28 
> >  gcc/testsuite/gcc.dg/Wformat-overflow2.c | 16 +
> >  3 files changed, 79 insertions(+), 7 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.dg/Wformat-overflow1.c
> >  create mode 100644 gcc/testsuite/gcc.dg/Wformat-overflow2.c
> >
> > diff --git a/gcc/gimple-ssa-sprintf.cc b/gcc/gimple-ssa-sprintf.cc
> > index c93f12f90b5..7f68c2b6e51 100644
> > --- a/gcc/gimple-ssa-sprintf.cc
> > +++ b/gcc/gimple-ssa-sprintf.cc
> > @@ -107,6 +107,15 @@ namespace {
> >
> >  static int warn_level;
> >
> > +/* b_overflow_flag depends on the current standart when using gcc */
>
> "standard"
>
> /* Comments should be formatted like this.  */
>
> > +static bool b_overflow_flag;
> > +
> > +/* check is current standart version equals C2X*/
> > +static bool check_std_c2x ()
> > +{
> > +  return !strcmp (lang_hooks.name, "GNU C2X");
> > +}
>
> Is this really needed?  ISTM that this new checking shouldn't depend on
> -std=c2x.  If not using C2X, you only get a warning if -Wpedantic.  So
> I think you should remove b_overflow_flag.
>
> >  /* The minimum, maximum, likely, and unlikely maximum number of bytes
> > of output either a formatting function or an individual directive
> > can result in.  */
> > @@ -535,6 +544,8 @@ fmtresult::type_max_digits (tree type, int base)
> >unsigned prec = TYPE_PRECISION (type);
> >switch (base)
> >  {
> > +case 2:
> > +  return prec;
> >  case 8:
> >return (prec + 2) / 3;
> >  case 10:
> > @@ -857,11 +868,11 @@ tree_digits (tree x, int base, HOST_WIDE_INT prec,
> bool plus, bool prefix)
> >
> >/* Adjust a non-zero value for the base prefix, either hexadecimal,
> >   or, unless precision has resulted in a leading zero, also octal.
> */
> > -  if (prefix && absval && (base == 16 || prec <= ndigs))
> > +  if (prefix && absval && (base == 2 || base == 16 || prec <= ndigs))
> >  {
> >if (base == 8)
> >   res += 1;
> > -  else if (base == 16)
> > +  else if (base == 16 || base == 2) /*0x...(0X...) and
> 0b...(0B...)*/
> >   res += 2;
> >  }
> >
> > @@ -1229,6 +1240,10 @@ format_integer (const directive &dir, tree arg,
> pointer_query &ptr_qry)
> >  case 'u':
> >base = 10;
> >break;
> > +case 'b':
> > +case 'B':
> > +  base = 2;
> > +  break;
> >  case 'o':
> >base = 8;
> >break;
> > @@ -1351,10 +1366,10 @@ format_integer (const directive &dir, tree arg,
> pointer_query &ptr_qry)
> >
> >/* Bump up the counters if WIDTH is greater than LEN.  */
> >res.adjust_for_width_or_precision (dir.width, dirtype, base,
> > -  (sign | maybebase) + (base ==
> 16));
> > +  (sign | maybebase) + (base == 2
> ||

Re: -Wformat-overflow handling for %b and %B directives in C2X standard

2022-04-01 Thread Marek Polacek via Gcc-patches
On Sat, Apr 02, 2022 at 12:19:47AM +0500, Frolov Daniil via Gcc-patches wrote:
> Hello, I've noticed that -Wformat-overflow doesn't handle %b and %B
> directives in the sprintf function. I've added a relevant issue in bugzilla
> (bug #105129).
> I attach a patch with a possible solution to the letter.

Thanks for the patch.  Support for C2X %b, %B formats is relatively new
(Oct 2021) so it looks like gimple-ssa-sprintf.cc hasn't caught up.

This is not a regression, so should probably wait till GCC 13.  Anyway...

> From 2051344e9500651f6e94c44cbc7820715382b957 Mon Sep 17 00:00:00 2001
> From: Frolov Daniil 
> Date: Fri, 1 Apr 2022 00:47:03 +0500
> Subject: [PATCH] Support %b, %B for -Wformat-overflow (sprintf, snprintf)
> 
> testsuite: add tests to check -Wformat-overflow on %b.
> Wformat-overflow1.c is compiled using -std=c2x so warning has to
> be throwed
> 
> Wformat-overflow2.c doesn't throw warnings cause c2x std isn't
> used
> 
> gcc/ChangeLog:
> 
>   * gimple-ssa-sprintf.cc
> (check_std_c2x): New function
>   (fmtresult::type_max_digits): add base == 2 handling
>   (tree_digits): add handle for base == 2
>   (format_integer): now handle %b and %B using base = 2
>   (parse_directive): add cases to handle %b and %B directives
>   (compute_format_length): add handling for base = 2

The descriptions should start with a capital letter and end with a period,
like "Handle base == 2."
 
> gcc/testsuite/ChangeLog:
> 
>   * gcc.dg/Wformat-overflow1.c: New test. (using -std=c2x)
>   * gcc.dg/Wformat-overflow2.c: New test. (-std=c11 no warning)

You can just say "New test."

> ---
>  gcc/gimple-ssa-sprintf.cc| 42 
>  gcc/testsuite/gcc.dg/Wformat-overflow1.c | 28 
>  gcc/testsuite/gcc.dg/Wformat-overflow2.c | 16 +
>  3 files changed, 79 insertions(+), 7 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/Wformat-overflow1.c
>  create mode 100644 gcc/testsuite/gcc.dg/Wformat-overflow2.c
> 
> diff --git a/gcc/gimple-ssa-sprintf.cc b/gcc/gimple-ssa-sprintf.cc
> index c93f12f90b5..7f68c2b6e51 100644
> --- a/gcc/gimple-ssa-sprintf.cc
> +++ b/gcc/gimple-ssa-sprintf.cc
> @@ -107,6 +107,15 @@ namespace {
>  
>  static int warn_level;
>  
> +/* b_overflow_flag depends on the current standart when using gcc */

"standard"

/* Comments should be formatted like this.  */

> +static bool b_overflow_flag;
> +
> +/* check is current standart version equals C2X*/
> +static bool check_std_c2x () 
> +{
> +  return !strcmp (lang_hooks.name, "GNU C2X");
> +}

Is this really needed?  ISTM that this new checking shouldn't depend on
-std=c2x.  If not using C2X, you only get a warning if -Wpedantic.  So
I think you should remove b_overflow_flag.

>  /* The minimum, maximum, likely, and unlikely maximum number of bytes
> of output either a formatting function or an individual directive
> can result in.  */
> @@ -535,6 +544,8 @@ fmtresult::type_max_digits (tree type, int base)
>unsigned prec = TYPE_PRECISION (type);
>switch (base)
>  {
> +case 2:
> +  return prec;
>  case 8:
>return (prec + 2) / 3;
>  case 10:
> @@ -857,11 +868,11 @@ tree_digits (tree x, int base, HOST_WIDE_INT prec, bool 
> plus, bool prefix)
>  
>/* Adjust a non-zero value for the base prefix, either hexadecimal,
>   or, unless precision has resulted in a leading zero, also octal.  */
> -  if (prefix && absval && (base == 16 || prec <= ndigs))
> +  if (prefix && absval && (base == 2 || base == 16 || prec <= ndigs))
>  {
>if (base == 8)
>   res += 1;
> -  else if (base == 16)
> +  else if (base == 16 || base == 2) /*0x...(0X...) and 0b...(0B...)*/
>   res += 2;
>  }
>  
> @@ -1229,6 +1240,10 @@ format_integer (const directive &dir, tree arg, 
> pointer_query &ptr_qry)
>  case 'u':
>base = 10;
>break;
> +case 'b':
> +case 'B':
> +  base = 2;
> +  break;
>  case 'o':
>base = 8;
>break;
> @@ -1351,10 +1366,10 @@ format_integer (const directive &dir, tree arg, 
> pointer_query &ptr_qry)
>  
>/* Bump up the counters if WIDTH is greater than LEN.  */
>res.adjust_for_width_or_precision (dir.width, dirtype, base,
> -  (sign | maybebase) + (base == 16));
> +  (sign | maybebase) + (base == 2 || 
> base == 16));
>/* Bump up the counters again if PRECision is greater still.  */
>res.adjust_for_width_or_precision (dir.prec, dirtype, base,
> -  (sign | maybebase) + (base == 16));
> +  (sign | maybebase) + (base == 2 || 
> base == 16));
>  
>return res;
>  }
> @@ -1503,7 +1518,7 @@ format_integer (const directive &dir, tree arg, 
> pointer_query &ptr_qry)
> if (res.range.min == 1)
>   res.range.likely += base == 8 ? 1 : 2;
> else if (re