public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-4372] Support %b, %B for -Wformat-overflow (sprintf, snprintf)
@ 2022-11-28 17:35 Jeff Law
0 siblings, 0 replies; only message in thread
From: Jeff Law @ 2022-11-28 17:35 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:aa353bd9a03b0d5ba92efe082b625d6c5ed6a79d
commit r13-4372-gaa353bd9a03b0d5ba92efe082b625d6c5ed6a79d
Author: Frolov Daniil <frolov.da@phystech.edu>
Date: Mon Nov 28 12:35:13 2022 -0500
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.
Diff:
---
gcc/gimple-ssa-sprintf.cc | 41 +++++++++++++++++++-------------
gcc/testsuite/gcc.dg/Wformat-overflow1.c | 28 ++++++++++++++++++++++
2 files changed, 53 insertions(+), 16 deletions(-)
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;
+
case 'p':
/* The %p output is implementation-defined. It's possible
to determine this format but due to extensions (especially
diff --git a/gcc/testsuite/gcc.dg/Wformat-overflow1.c b/gcc/testsuite/gcc.dg/Wformat-overflow1.c
new file mode 100644
index 00000000000..cf9766fae14
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wformat-overflow1.c
@@ -0,0 +1,28 @@
+/*
+ { dg-do compile }
+ { dg-options "-Wformat-overflow -std=c2x" }
+*/
+
+extern int sprintf (char* restrict, const char* restrict, ...);
+
+void test_warn () {
+
+ int n = __INT_MAX__;
+ char dst [5] = {0};
+ sprintf (dst, "%b", n); /* { dg-warning "-Wformat-overflow" } */
+
+ sprintf (dst, "%#b", n); /* { dg-warning "-Wformat-overflow" } */
+
+}
+
+void test_no_warn () {
+
+ char dst [5] = {0};
+ int n = 8;
+ sprintf (dst, "%b", n);
+
+ char another_dst [34] = {0};
+ n = __INT_MAX__;
+ sprintf (another_dst, "%#b", n);
+
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-11-28 17:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-28 17:35 [gcc r13-4372] Support %b, %B for -Wformat-overflow (sprintf, snprintf) Jeff Law
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).