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

            Bug ID: 95594
           Summary: overzealous -Wmaybe-uninitialized calling a function
                    with an empty range of const pointers
           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: ---

The recent enhancement to -Wuninitialized (PR 10138) is overly strict: it
triggers for calls to functions with a pair of pointers (at least one const)
delineating a slice of an array.

For example, while the warning doesn't trigger in g() below it does trigger in
h(), even though the call is safe.  Passing such slices is not entirely
uncommon.  For example, the C++ class member functions in() and out() are
declared like so:

  result codevt::out (stateT& state,
                      const internT* from, const internT* from_end, const
internT*& from_next,
                      externT*to, externT* to_end, externT*& to_next) const;

and can be called with empty ranges.

A test case for the idiom is below:

$ cat q.c && /build/gcc-master/gcc/xgcc -B /build/gcc-master/gcc -O2 -S -Wall
-Wextra q.c
__attribute__ ((noipa)) void
f (void *to, const void *to_end)
{
  __builtin_memset (to, 0, to_end - to);
}

void g (void)
{
  int i;
  f (&i, &i + 1);  // no warning (good)
  // ...
}

void h (void)
{
  int a[2];
  f (a, a);        // -Wmaybe-uninitialized
  // ...
}

q.c: In function ‘h’:
q.c:17:3: warning: ‘a’ may be used uninitialized [-Wmaybe-uninitialized]
   17 |   f (a, a);        // -Wmaybe-uninitialized
      |   ^~~~~~~~
q.c:2:1: note: by argument 2 of type ‘const void *’ to ‘f’ declared here
    2 | f (void *to, const void *to_end)
      | ^
q.c:16:7: note: ‘a’ declared here
   16 |   int a[2];
      |       ^

Reply via email to