Bug 79496 - call to snprintf eliminated with -Wformat-truncation=2
Summary: call to snprintf eliminated with -Wformat-truncation=2
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 7.0
: P3 normal
Target Milestone: ---
Assignee: Martin Sebor
URL:
Keywords: patch, wrong-code
Depends on:
Blocks:
 
Reported: 2017-02-13 17:55 UTC by Martin Sebor
Modified: 2017-02-14 04:40 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-02-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2017-02-13 17:55:05 UTC
As pointed out in bug 79448 comment 3, using -Wformat-truncation=2 results in eliminating calls to snprintf with a non-constant size argument the lower bound of whose range is zero.  The following small test case demonstrates the problem.

$ cat u.c && gcc -O2 -S -Wformat-truncation=2 -fdump-tree-printf-return-value=/dev/stdout u.c
void f (void*);

int g (char *d, unsigned n)
{
  if (4 < n)
    n = 4;
  return __builtin_snprintf (d, n, "%i", 123);
}

;; Function g (g, funcdef_no=0, decl_uid=1798, cgraph_uid=0, symbol_order=0)

u.c:7: __builtin_snprintf: objsize = 9223372036854775807, fmtstr = "%i"
  Directive 1 at offset 0: "%i"
    Result: 3, 3, 3, 3 (3, 3, 3, 3)
  Directive 2 at offset 2: "", length = 1
  Substituting 3 for statement.

g (char * d, unsigned int n)
{
  long unsigned int _1;
  int _7;

  <bb 2> [100.00%]:
  n_8 = MIN_EXPR <n_3(D), 4>;
  _1 = (long unsigned int) n_8;
  _7 = 3;
  return _7;

}
Comment 1 Martin Sebor 2017-02-13 17:55:42 UTC
Testing a patch.
Comment 2 Martin Sebor 2017-02-13 20:58:57 UTC
Patch submitted for review:
https://gcc.gnu.org/ml/gcc-patches/2017-02/msg00851.html
Comment 3 Martin Sebor 2017-02-14 04:39:26 UTC
Author: msebor
Date: Tue Feb 14 04:38:54 2017
New Revision: 245415

URL: https://gcc.gnu.org/viewcvs?rev=245415&root=gcc&view=rev
Log:
PR middle-end/79496 - call to snprintf with zero size eliminated with -Wformat-truncation=2

gcc/ChangeLog:

	PR middle-end/79496
	* gimple-ssa-sprintf.c (pass_sprintf_length::handle_gimple_call): Avoid
	clearing info.nowrite flag when snprintf size argument is a range.

gcc/testsuite/ChangeLog:

	PR middle-end/79496
	* gcc.dg/tree-ssa/builtin-snprintf-2.c: New test.


Added:
    trunk/gcc/testsuite/gcc.dg/tree-ssa/builtin-snprintf-2.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/gimple-ssa-sprintf.c
    trunk/gcc/testsuite/ChangeLog
Comment 4 Martin Sebor 2017-02-14 04:40:07 UTC
Fixed via r245415.