diff mbox series

[committed] avoid two more ICEs in print_mem_ref (PR c/98597)

Message ID 16565216-8447-9abf-e657-ef33cda0af59@gmail.com
State New
Headers show
Series [committed] avoid two more ICEs in print_mem_ref (PR c/98597) | expand

Commit Message

Martin Sebor Jan. 12, 2021, 8:12 p.m. UTC
A recent improvement to MEM_REF formatting introduced a few invalid
assumptions that didn't get exposed during testing and ended up
causing ICEs in downstream packages and some distress to their
maintainers.  I have committed the attached patch to remove two
of these assumptions and unblock the package builds.

Since the MEM_REF formatting is clearly not being sufficiently
exercised by the test suite I've also instrumented GCC to format
every MEM_REF the uninit pass comes across, independent of whether
or nor it is initialized, and will build a few packages with it
to uncover any outstanding bugs.

Martin
diff mbox series

Patch

commit 5a9cfad2de92f2d65585774acb524b3fa17621b5
Author: Martin Sebor <msebor@redhat.com>
Date:   Tue Jan 12 12:58:27 2021 -0700

    Avoid a couple more ICEs in print_mem_ref (PR c/98597).
    
    Resolves:
    PR c/98597 - ICE in -Wuninitialized printing a MEM_REF
    PR c/98592 - ICE in gimple_canonical_types_compatible_p while formatting
    
    gcc/c-family/ChangeLog:
    
            PR c/98597
            PR c/98592
            * c-pretty-print.c (print_mem_ref): Avoid assuming MEM_REF operand
            has pointer type.  Remove redundant code.  Avoid calling
            gimple_canonical_types_compatible_p.
    
    gcc/testsuite/ChangeLog:
    
            PR c/98597
            PR c/98592
            * g++.dg/warn/Wuninitialized-13.C: New test.
             gcc.dg/uninit-39.c: New test.
    
            #

diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index 87301a2091c..4d17c270b16 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -1847,10 +1847,11 @@  print_mem_ref (c_pretty_printer *pp, tree e)
   tree access_type = TREE_TYPE (e);
   if (TREE_CODE (access_type) == ARRAY_TYPE)
     access_type = TREE_TYPE (access_type);
-  tree arg_type = TREE_TYPE (TREE_TYPE (arg));
+  tree arg_type = TREE_TYPE (arg);
+  if (POINTER_TYPE_P (arg_type))
+    arg_type = TREE_TYPE (arg_type);
   if (TREE_CODE (arg_type) == ARRAY_TYPE)
     arg_type = TREE_TYPE (arg_type);
-
   if (tree access_size = TYPE_SIZE_UNIT (access_type))
     if (TREE_CODE (access_size) == INTEGER_CST)
       {
@@ -1866,16 +1867,13 @@  print_mem_ref (c_pretty_printer *pp, tree e)
 
   /* True to include a cast to the accessed type.  */
   const bool access_cast = VOID_TYPE_P (arg_type)
-    || !gimple_canonical_types_compatible_p (access_type, arg_type);
+    || TYPE_MAIN_VARIANT (access_type) != TYPE_MAIN_VARIANT (arg_type);
 
   if (byte_off != 0)
     {
       /* When printing the byte offset for a pointer to a type of
 	 a different size than char, include a cast to char* first,
 	 before printing the cast to a pointer to the accessed type.  */
-      tree arg_type = TREE_TYPE (TREE_TYPE (arg));
-      if (TREE_CODE (arg_type) == ARRAY_TYPE)
-	arg_type = TREE_TYPE (arg_type);
       offset_int arg_size = 0;
       if (tree size = TYPE_SIZE (arg_type))
 	arg_size = wi::to_offset (size);
diff --git a/gcc/testsuite/g++.dg/warn/Wuninitialized-13.C b/gcc/testsuite/g++.dg/warn/Wuninitialized-13.C
new file mode 100644
index 00000000000..49ee878806a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wuninitialized-13.C
@@ -0,0 +1,28 @@ 
+/* PR c/98597 - ICE in -Wuninitialized printing a MEM_REF
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+struct shared_count {
+  shared_count () { }
+  shared_count (shared_count &r)
+    : pi (r.pi) { }     // { dg-warning "\\\[-Wuninitialized" }
+  int pi;
+};
+
+// There's another (redundant) -Wuninitialized on the line below.
+struct shared_ptr {
+  int ptr;
+  shared_count refcount;
+};
+
+struct Bar {
+  Bar (int, shared_ptr);
+};
+
+void g () {
+  shared_ptr foo;
+  Bar (0, foo);
+}
+
+// Prune out duplicates.
+// { dg-prune-output "-Wuninitialized" }
diff --git a/gcc/testsuite/gcc.dg/uninit-39.c b/gcc/testsuite/gcc.dg/uninit-39.c
new file mode 100644
index 00000000000..0f918542773
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-39.c
@@ -0,0 +1,47 @@ 
+/* PR c/98592 - ICE in gimple_canonical_types_compatible_p while formatting
+   a MEM_REF
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+void f (int);
+
+void vlaNx3_to_pia1 (int n)
+{
+  int a[n][3];
+
+  /* The VLA isn't formatted correctly due to PR 98587.  Just verify
+     there is no ICE and a warning is issued.  */
+  f (((*(int(*)[4])&a[1][2]))[3]);      // { dg-warning "\\\[-Wuninitialized" }
+}
+
+void vlaNxN_to_pia1 (int n)
+{
+  int a[n][n];
+
+  /* Same as above.  */
+  f (((*(int(*)[4])&a[1][2]))[3]);      // { dg-warning "\\\[-Wuninitialized" }
+}
+
+void vlaNxN_to_pvla4xN (int n)
+{
+  int a[n][n];
+
+  /* Same as above.  */
+  f (((*(int(*)[4][n])&a[1][2]))[3][4]);  // { dg-warning "\\\[-Wuninitialized" }
+}
+
+void vlaN_to_pia2 (int n)
+{
+  int a[n];
+
+  /* Same as above.  */
+  f (((*(int(*)[3][4])&a[1]))[2][3]);   // { dg-warning "\\\[-Wuninitialized" }
+}
+
+void vlaN_to_pvlaNx4 (int n)
+{
+  int a[n];
+
+  /* Same as above.  */
+  f (((*(int(*)[n][4])&a[1]))[1][3]);   // { dg-warning "\\\[-Wuninitialized" }
+}