The VLA bounds that are included by the C front end to attribute access added to functions with VLA parameters to help detect redeclaratations of function with "mismatched" VLA bounds are cleared by the free_lang_data pass before the IL reaches the middle end. The clearing was done to fix pr97172 on the basis that the bounds aren't used by the middle end to trigger any warnings. While that's true, it turns out that the bounds are sometimes used when formatting informational notes. I forgot about that when implementing the final revision of the patch for pr97172 and removing the assumptions that the bounds are nonnull.
The attached patch removes the (hopefully last) assumption that the bounds are nonnull. I reviewed the code and didn't find any others. Bootstrapped & tested on x86_64-linux. Martin
PR middle-end/100250 - ICE related to -Wmaybe-uninitialized gcc/ChangeLog: PR middle-end/100250 * attribs.c (attr_access::array_as_string): Avoid dereferencing a pointer when it's null. gcc/testsuite/ChangeLog: PR middle-end/100250 * gcc.dg/uninit-pr100250.c: New test. diff --git a/gcc/attribs.c b/gcc/attribs.c index 3ffa1b6bc81..ebc0783c439 100644 --- a/gcc/attribs.c +++ b/gcc/attribs.c @@ -2388,7 +2388,8 @@ attr_access::array_as_string (tree type) const const char *p = end; for ( ; p != str && *p-- != ']'; ); if (*p == '$') - index_type = build_index_type (TREE_VALUE (size)); + /* SIZE may have been cleared. Use it with care. */ + index_type = build_index_type (size ? TREE_VALUE (size) : size); } else if (minsize) index_type = build_index_type (size_int (minsize - 1)); diff --git a/gcc/testsuite/gcc.dg/uninit-pr100250.c b/gcc/testsuite/gcc.dg/uninit-pr100250.c new file mode 100644 index 00000000000..8e7a787ddac --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr100250.c @@ -0,0 +1,29 @@ +/* PR middle-end/100250 - ICE related to -Wmaybe-uninitialized + { dg-do compile } + { dg-options "-O2 -Wall" } */ + +extern void f (int D, const int[D], const int[D]); + +void g (int D, const int a[D], const int b[D], const int c[D], const int d[D]) +{ + int c2[D]; + + for (int i = 0; i < D; i++) { + + if (a[i] >= D) __builtin_abort (); + if (b[i] != d[a[i]]) __builtin_abort (); + + c2[a[i]] = c[i]; + } + + f (D, d, c2); +} + +void h (int D, const int d[D]) +{ + int a[D]; + int b[D]; + int c[D]; + + g (D, a, b, c, d); // { dg-warning "-Wmaybe-uninitialized" } +}