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

            Bug ID: 80202
           Summary: Spurious warning "array subscript is below array
                    bounds" with if-statement and char to unsigned int
                    conversion
           Product: gcc
           Version: 6.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: mchtly at gmail dot com
  Target Milestone: ---

When compiling the following example with "g++ -Warray-bounds -O2", I get
spurious warnings:

// This type doesn't matter.
#define T int

T ac[2]; // No warning if this is static.
void foo(T); // No warning if this is defined.

enum {
  ACM0 = 1, // This value must be greater than zero.
  ACM1 // This value may be any non-negative integer.
};

// The parameter to srs() must be unsigned, the parameter to read()
// must be signed, and the first must be smaller than the second.
static_assert(sizeof(unsigned char) < sizeof(int), "");

T read(int reg) {
  switch (reg) {
  // No warning if either case statement is removed. Additional cases
  // may be added anywhere.
  case ACM0:
  case ACM1:
    return ac[reg - ACM0];
  // The default case statement may be removed, and is only included
  // for completeness.
  default:
    return 0;
  }
}

void srs(unsigned char reg) {
  if (reg < ACM0)
    // Warning only if the return value of read() is passed to foo()
    // at some point.
    foo(read(reg));
}


And the output from GCC is:

$ g++ -c test.cpp -Warray-bounds -O2
test.cpp: In function 'void srs(unsigned char)':
test.cpp:22:25: warning: array subscript is below array bounds [-Warray-bounds]
     return ac[reg - ACM0];
            ~~~~~~~~~~~~~^

Reply via email to