Created attachment 43111 [details] Small test case The attached sample C++ program fails compilation with this error: $ /usr/lib/gcc-snapshot/bin/g++ -std=c++17 -c broken.cc broken.cc: In function 'void f()': broken.cc:9:3: internal compiler error: in process_init_constructor_array, at cp/typeck2.c:1318 }; ^ Please submit a full bug report, with preprocessed source if appropriate. See <file:///usr/share/doc/gcc-snapshot/README.Bugs> for instructions. If I've understood the standard correctly, the expression used as the size of the array should be a constexpr, and the compiler should complain about it. Asking the user to file a bug report instead of fixing their code is the wrong response. $ /usr/lib/gcc-snapshot/bin/g++ -v Using built-in specs. COLLECT_GCC=/usr/lib/gcc-snapshot/bin/g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc-snapshot/libexec/gcc/x86_64-linux-gnu/8/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 20180107-1' --with-bugurl=file:///usr/share/doc/gcc-snapshot/README.Bugs --enable-languages=c,ada,c++,go,brig,fortran,objc,obj-c++ --prefix=/usr/lib/gcc-snapshot --with-gcc-major-version-only --program-prefix= --enable-shared --enable-linker-build-id --disable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --enable-checking=yes --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 8.0.0 20180107 (experimental) [trunk revision 256322] (Debian 20180107-1) I know that this comes from a Debian release, but the code is 100% the same (the code itself is not patched). I've found the same error in version 7.2.0. Version 6.4.0 instead accepts the code without complaining.
Confirmed. Bisection points to r246662 (introduced in gcc 7.0.1): r246662 | jason | 2017-04-03 17:15:36 -0400 (Mon, 03 Apr 2017) | 7 lines PR sanitizer/79993 - ICE with VLA initialization from string PR c++/69487 - wrong VLA initialization from string * init.c (finish_length_check): Split out from build_vec_init. (build_vec_init): Handle STRING_CST. * typeck2.c (split_nonconstant_init): Handle STRING_CST. (digest_init_r): Don't give a STRING_CST VLA type.
Slightly adjusted testcase: struct R { int r; }; void foo () { const R a = { 12 }; char b[1][a.r] = { { "12345678901" } }; char c[a.r] = { "12345678901" }; } It isn't enough to just comment out the assertion, for c we generate runtime code to check that the string fits in, but not for b[0].
Seems one of the issues is that array_of_runtime_bound_p only looks at the toplevel array. Shall it look at all the nested ARRAY_TYPEs and return true if any of them is of runtime bound? Or shall we have another predicate which would do that? There is always variably_modified_type_p predicate, but it doesn't probably work too well with dependent types.
--- gcc/cp/tree.c.jj 2018-01-17 11:54:08.669802704 +0100 +++ gcc/cp/tree.c 2018-01-17 13:11:08.524278851 +0100 @@ -1044,11 +1044,14 @@ array_of_runtime_bound_p (tree t) if (!t || TREE_CODE (t) != ARRAY_TYPE) return false; tree dom = TYPE_DOMAIN (t); - if (!dom) - return false; - tree max = TYPE_MAX_VALUE (dom); - return (!potential_rvalue_constant_expression (max) - || (!value_dependent_expression_p (max) && !TREE_CONSTANT (max))); + if (dom) + { + tree max = TYPE_MAX_VALUE (dom); + if (!potential_rvalue_constant_expression (max) + || (!value_dependent_expression_p (max) && !TREE_CONSTANT (max))) + return true; + } + return array_of_runtime_bound_p (TREE_TYPE (t)); } /* Return a reference type node referring to TO_TYPE. If RVAL is isn't sufficient either though.
Another case: struct R { int r; }; void baz (char *, char *, char *, char *); void foo () { const R a = { 12 }; char b[1][a.r] = { { "12345678901" } }; char c[a.r] = { "12345678901" }; char d[1][a.r] = { { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '\0' } }; char e[a.r] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '1', '\0' }; baz (b[0], c, d[0], e); } plus perhaps we want a runtime test that checks what happens if the VLA sizes will be too small.
GCC 7.3 is being released, adjusting target milestone.
Author: jason Date: Thu Apr 5 17:17:11 2018 New Revision: 259138 URL: https://gcc.gnu.org/viewcvs?rev=259138&root=gcc&view=rev Log: PR c++/83808 - ICE with VLA initialization. * typeck2.c (process_init_constructor_array): Don't require a VLA initializer to have VLA type. Added: trunk/gcc/testsuite/g++.dg/ext/vla19.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/typeck2.c
Fixed in GCC 8.