Bug 70075 - incorrect initialization of multidimensional VLAs
Summary: incorrect initialization of multidimensional VLAs
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
: 95993 (view as bug list)
Depends on:
Blocks: C++VLA
  Show dependency treegraph
 
Reported: 2016-03-04 03:50 UTC by Martin Sebor
Modified: 2021-10-01 07:24 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 4.9.3, 5.3.0, 6.0
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Sebor 2016-03-04 03:50:57 UTC
Unlike GCC in C mode, G++ accepts explicitly initialized variable length arrays (as specified in WG21 N3639, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html).  However, when initializing VLAs with more elements than explicitly specified in the initializer, G++ fails to zero-initialize the remaining elements as would be the case for ordinary arrays.

The following test case demonstrates the problem:

 cat z.cpp && /build/gcc-trunk/gcc/xgcc -B /build/gcc-trunk/gcc -Wall -Wextra -Wpedantic z.cpp && ./a.out
void __attribute__ ((noclone, noinline)) bar (int n)
{
  const int m = 2;
  char a [m][n] = { { 0, 1, 2 } };

  for (int i = 0; i < m; ++i)
    for (int j = 0; j < n; ++j)
      __builtin_printf ("%hhi ", a [i][j]);
  __builtin_printf ("\n");

  if (a [0][n - 1] != 0)
    __builtin_abort ();
}

int main ()
{
    bar (4);
}
z.cpp: In function ‘void bar(int)’:
z.cpp:4:15: warning: ISO C++ forbids variable length array ‘a’ [-Wvla]
   char a [m][n] = { { 0, 1, 2 } };
               ^
0 1 2 12 -1 127 0 0 
Aborted (core dumped)
Comment 1 Richard Biener 2016-03-04 08:42:41 UTC
I believe this case is simply not supported by the output machinery.  It's probably substantial work to get it working unless the FE always emits
a full zero init of the VLA and then the partial init from the CONSTRUCTOR.
Comment 2 Eric Gallager 2017-08-28 12:04:26 UTC
(In reply to Martin Sebor from comment #0)
> Unlike GCC in C mode, G++ accepts explicitly initialized variable length
> arrays (as specified in WG21 N3639,
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html). 
> However, when initializing VLAs with more elements than explicitly specified
> in the initializer, G++ fails to zero-initialize the remaining elements as
> would be the case for ordinary arrays.
> 
> The following test case demonstrates the problem:
> 
>  cat z.cpp && /build/gcc-trunk/gcc/xgcc -B /build/gcc-trunk/gcc -Wall
> -Wextra -Wpedantic z.cpp && ./a.out
> void __attribute__ ((noclone, noinline)) bar (int n)
> {
>   const int m = 2;
>   char a [m][n] = { { 0, 1, 2 } };
> 
>   for (int i = 0; i < m; ++i)
>     for (int j = 0; j < n; ++j)
>       __builtin_printf ("%hhi ", a [i][j]);
>   __builtin_printf ("\n");
> 
>   if (a [0][n - 1] != 0)
>     __builtin_abort ();
> }
> 
> int main ()
> {
>     bar (4);
> }
> z.cpp: In function ‘void bar(int)’:
> z.cpp:4:15: warning: ISO C++ forbids variable length array ‘a’ [-Wvla]
>    char a [m][n] = { { 0, 1, 2 } };
>                ^
> 0 1 2 12 -1 127 0 0 
> Aborted (core dumped)

I get this output on i386-apple-darwin9.8.0 with gcc8:

$ /usr/local/bin/g++ -Wall -Wextra -Wpedantic -o 70075.exe 70075.cc
70075.cc: In function ‘void bar(int)’:
70075.cc:4:13: warning: ISO C++ forbids variable length array ‘a’ [-Wvla]
  char a[m][n] = { { 0, 1, 2 } };
             ^
$ ./70075.exe
0 1 2 0 0 0 -32 -113 
$

(i.e. no errors)
Comment 3 Eric Gallager 2019-05-28 05:49:13 UTC
(In reply to Eric Gallager from comment #2)
> 
> I get this output on i386-apple-darwin9.8.0 with gcc8:
> 
> $ /usr/local/bin/g++ -Wall -Wextra -Wpedantic -o 70075.exe 70075.cc
> 70075.cc: In function ‘void bar(int)’:
> 70075.cc:4:13: warning: ISO C++ forbids variable length array ‘a’ [-Wvla]
>   char a[m][n] = { { 0, 1, 2 } };
>              ^
> $ ./70075.exe
> 0 1 2 0 0 0 -32 -113 
> $
> 
> (i.e. no errors)

Running the program on x86_64-apple-darwin10.8.0 with gcc9, it prints this instead:
0 1 2 0 9 0 0 0
(still no errors though)
Comment 4 Martin Sebor 2020-07-01 00:23:27 UTC
*** Bug 95993 has been marked as a duplicate of this bug. ***
Comment 5 Eric Gallager 2020-11-03 05:26:30 UTC
(In reply to Eric Gallager from comment #3)
> (In reply to Eric Gallager from comment #2)
> > 
> > I get this output on i386-apple-darwin9.8.0 with gcc8:
> > 
> > $ /usr/local/bin/g++ -Wall -Wextra -Wpedantic -o 70075.exe 70075.cc
> > 70075.cc: In function ‘void bar(int)’:
> > 70075.cc:4:13: warning: ISO C++ forbids variable length array ‘a’ [-Wvla]
> >   char a[m][n] = { { 0, 1, 2 } };
> >              ^
> > $ ./70075.exe
> > 0 1 2 0 0 0 -32 -113 
> > $
> > 
> > (i.e. no errors)
> 
> Running the program on x86_64-apple-darwin10.8.0 with gcc9, it prints this
> instead:
> 0 1 2 0 9 0 0 0
> (still no errors though)

Update for gcc 11 on x86_64-apple-darwin19.6.0:
0 1 2 0 0 0 0 0
So, not only are there no errors now, but it also looks like everything after the "0 1 2" is now properly zero-initialized? FIXED?