This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/83296] New: missing -Wstringop-overflow due to missing range info for MAX_EXPR


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83296

            Bug ID: 83296
           Summary: missing -Wstringop-overflow due to missing range info
                    for MAX_EXPR
           Product: gcc
           Version: 8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The call to strncpy() in the program below overflows the destination by 1 byte.
 The overflow is diagnosed when compiled by GCC (as a C program) but not when
compiled by G++ (as a C++ program).  The only difference between the two is
that in C, the prephitmp_10 strncpy argument has range info attached to it,
while in C++ it does not.  As a result, the get_range_info() function used to
retrieve the range succeeds in C but fails in C++.

$ (set -x && cat a.c && for lang in c c++; do gcc -O2 -S -Wstringop-overflow=2
-fdump-tree-optimized=/dev/stdout -x$lang a.c; done)
+ cat a.c
struct S {
  char a[5];
  void (*pf)(void);
};

void f (struct S *s, int n)
{
  if (n < sizeof s->a + 1)
    n = sizeof s->a + 1;

  __builtin_strncpy (s->a, "123456", n);   // missing warning in C++
}
+ for lang in c c++
+ gcc -O2 -S -Wstringop-overflow=2 -fdump-tree-optimized=/dev/stdout -xc a.c

;; Function f (f, funcdef_no=0, decl_uid=1897, cgraph_uid=0, symbol_order=0)

f (struct S * s, int n)
{
  unsigned int n.0_1;
  char[5] * _3;
  int _4;
  long unsigned int prephitmp_10;

  <bb 2> [local count: 1073741825]:
  n.0_1 = (unsigned int) n_5(D);
  if (n.0_1 <= 5)
    goto <bb 3>; [50.00%]
  else
    goto <bb 4>; [50.00%]

  <bb 3> [local count: 536870913]:

  <bb 4> [local count: 1073741825]:
  # _4 = PHI <n_5(D)(2), 6(3)>
  prephitmp_10 = (long unsigned int) _4;   // has range info
  _3 = &s_6(D)->a;
  __builtin_strncpy (_3, "123456", prephitmp_10); [tail call]
  return;

}


a.c: In function ‘f’:
a.c:11:3: warning: ‘__builtin_strncpy’ writing 6 or more bytes into a region of
size 5 overflows the destination [-Wstringop-overflow=]
   __builtin_strncpy (s->a, "123456", n);   // missing warning in C++
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ for lang in c c++
+ gcc -O2 -S -Wstringop-overflow=2 -fdump-tree-optimized=/dev/stdout -xc++ a.c

;; Function f (_Z1fP1Si, funcdef_no=0, decl_uid=2330, cgraph_uid=0,
symbol_order=0)

f (struct S * s, int n)
{
  long unsigned int _1;
  char[5] * _3;
  long unsigned int prephitmp_4;

  <bb 2> [local count: 1073741825]:
  _1 = (long unsigned int) n_5(D);
  prephitmp_4 = MAX_EXPR <6, _1>;   // no range info
  _3 = &s_6(D)->a;
  __builtin_strncpy (_3, "123456", prephitmp_4); [tail call]
  return;

}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]