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

            Bug ID: 91235
           Summary: Array size expression is implicitly casted to unsigned
                    long type
           Product: gcc
           Version: 9.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bugzi...@poradnik-webmastera.com
  Target Milestone: ---

[code]
void foo(char*);

inline void bar(int n)
{
    if (__builtin_constant_p(n))
    {
        char a[(int)(n == 2 ? -1 : 0)];
        foo(a);
    }
}

void baz()
{
    bar(2);
}
[/code]

When this is compiled with -O3 -Wall -Wextra -std=c++11 (tested via
godbolt.org), it produces following code:

[asm]
baz():
  push rbp
  mov rbp, rsp
  mov rdi, rsp
  call foo(char*)
  leave
  ret
[/asm]

During compilation gcc reported following warning:
[out]
<source>: In function 'void baz()':

<source>:7:14: warning: argument to variable-length array is too large
[-Wvla-larger-than=]

    7 |         char a[(int)(n == 2 ? -1 : 0)];

      |              ^

<source>:7:14: note: limit is 9223372036854775807 bytes, but argument is
18446744073709551615

Compiler returned: 0
[out]

This means that gcc saw that n is constant, and then expression specified as
array size was evaluated and implicitly casted to unsigned type.

When I removed "foo(a);" line, this warning is gone, and gcc warned about
unused variable.

When -1 is specified as array size, it correctly report error that array size
is negative. Looks that only expressions causes this issue.

Reply via email to