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

            Bug ID: 93708
           Summary: missing warning on memset overflow with transposed
                    arguments
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

GCC diagnoses some suspicious memset calls whose last two arguments look like
they may have been transposed by -Wmemset-transposed-args just as long as the
last argument is zero.

But it doesn't diagnose other similarly suspicious calls with a non-zero last
argument.  What's more, it silently folds away such calls even if they write
past the end of the object, replacing them with stores to the object itself (if
possible).  Folding buffer overflows away may be a reasonable strategy in some
cases but it's certainly the wrong thing to do with no warning in cases where
the in-bounds store most likely ends up setting the data to the wrong
(transposed) value.

The buffer overflow here should be diagnosed regardless of whether or not it's
eliminated.  In addition, it might be worth to also consider enhancing
-Wmemset-transposed-args to diagnose even calls with a non-zero last argument.

$ cat z.c && gcc -O2 -S -Wall -Wextra -Wpedantic
-fdump-tree-optimized=/dev/stdout z.c
void f (int, ...);

struct S { int x, y, z; };

void f0 (void)
{
  struct S *p = __builtin_alloca (sizeof *p);

  __builtin_memset (p, sizeof *p, 0);    // -Wmemset-transposed-args
  f (p->x, p->y, p->z);                  // missing -Wuninitialized
}

void f1 (void)
{
  struct S s;
  __builtin_memset (&s, sizeof s, -1);   // missing warning
  f (s.x, s.y, s.z);
}
z.c: In function ‘f0’:
z.c:9:3: warning: ‘memset’ used with constant zero length parameter; this could
be due to transposed parameters [-Wmemset-transposed-args]
    9 |   __builtin_memset (p, sizeof *p, 0);    // -Wmemset-transposed-args
      |   ^~~~~~~~~~~~~~~~

;; Function f0 (f0, funcdef_no=0, decl_uid=1936, cgraph_uid=1, symbol_order=0)

f0 ()
{
  struct S * p;
  int _1;
  int _2;
  int _3;

  <bb 2> [local count: 1073741824]:
  p_6 = __builtin_alloca (12);
  _1 = p_6->z;
  _2 = p_6->y;
  _3 = p_6->x;
  f (_3, _2, _1);
  return;

}



;; Function f1 (f1, funcdef_no=1, decl_uid=1940, cgraph_uid=2, symbol_order=1)

f1 ()
{
  <bb 2> [local count: 1073741824]:
  f (202116108, 202116108, 202116108); [tail call]
  return;

}

Reply via email to