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" }
+}

Reply via email to