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

            Bug ID: 70076
           Summary: no exception for excess initializer elements in a
                    multidimensional VLA
           Product: gcc
           Version: 4.9.3
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: msebor at gcc dot gnu.org
  Target Milestone: ---

The G++ 4.9 Changes document (https://gcc.gnu.org/gcc-4.9/changes.html) claims
support for C++ VLAs including initializers (as specified in N3639).  The N3639
proposal specifies that the /expression/ denoting the number of elements in a
VLA declaration is erroneous when "the initializer of the object is a
braced-init-list whose number of (top-level) initializer-clauses exceeds the
number of elements to initialize."  The proposal then goes on to say that if an
/expression/ that is not a core-constant expression is erroneous, an exception
of a type that would match a handler (15.3 except.handle) of type
std::bad_array_length (18.6.2.2 xxx) is thrown."

The following test case shows an example where G++ fails to follow this
requirement.

AFAICS, the problem is that this checking in G++ 4.9 is implemented in the
wrong function (build_vec_init() in cp/init.c).  The checking needs to be done
in its caller, store_init_value(), because it only calls build_vec_init() when
array_of_runtime_bound_p(type) is true, and that function only consider the
major rank of the array, not any of its minor ranks).

$ cat z.cpp && /home/msebor/build/gcc-4.9.3/gcc/xgcc
-B/home/msebor/build/gcc-4.9.3/gcc  -Wall -Wextra -Wpedantic -xc++ z.cpp &&
./a.out 
void __attribute__ ((noclone, noinline)) foo (void*) { }
void __attribute__ ((noclone, noinline)) bar (int n)
{
  char a [1][n] = { { 0, 1, 2 } };
  foo (a);
}

int main ()
{
  try {
    bar (1);
    __builtin_abort ();
  }
  catch (...) {
  }
}
z.cpp: In function ‘void bar(int)’:
z.cpp:4:15: warning: ISO C++ forbids variable length array ‘a’ [-Wvla]
   char a [1][n] = { { 0, 1, 2 } };
               ^
Aborted (core dumped)

Reply via email to