Initialize type_warnings::dyn_count with a default value (PR ipa/83054).
authorMartin Liska <mliska@suse.cz>
Fri, 12 Jan 2018 08:59:52 +0000 (09:59 +0100)
committerMartin Liska <marxin@gcc.gnu.org>
Fri, 12 Jan 2018 08:59:52 +0000 (08:59 +0000)
2018-01-12  Martin Liska  <mliska@suse.cz>

PR ipa/83054
* ipa-devirt.c (final_warning_record::grow_type_warnings):
New function.
(possible_polymorphic_call_targets): Use it.
(ipa_devirt): Likewise.
2018-01-12  Martin Liska  <mliska@suse.cz>

PR ipa/83054
* g++.dg/warn/pr83054.C: New test.

From-SVN: r256566

gcc/ChangeLog
gcc/ipa-devirt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/warn/pr83054.C [new file with mode: 0644]

index 3dff3ed65ce95077ed43360e2abdfd8576b760b3..5ed1111f9bd4e510caae3ec39adda95aa705149e 100644 (file)
@@ -1,3 +1,11 @@
+2018-01-12  Martin Liska  <mliska@suse.cz>
+
+       PR ipa/83054
+       * ipa-devirt.c (final_warning_record::grow_type_warnings):
+       New function.
+       (possible_polymorphic_call_targets): Use it.
+       (ipa_devirt): Likewise.
+
 2018-01-12  Martin Liska  <mliska@suse.cz>
 
        * profile-count.h (enum profile_quality): Use 0 as invalid
index 8de004fef63f16237ff8c1cfbb0512472d8076e6..cc551d636fd7c5e097858af4fc5db8dff99d69b1 100644 (file)
@@ -2901,10 +2901,27 @@ struct decl_warn_count
 
 struct final_warning_record
 {
+  /* If needed grow type_warnings vector and initialize new decl_warn_count
+     to have dyn_count set to profile_count::zero ().  */
+  void grow_type_warnings (unsigned newlen);
+
   profile_count dyn_count;
   auto_vec<odr_type_warn_count> type_warnings;
   hash_map<tree, decl_warn_count> decl_warnings;
 };
+
+void
+final_warning_record::grow_type_warnings (unsigned newlen)
+{
+  unsigned len = type_warnings.length ();
+  if (newlen > len)
+    {
+      type_warnings.safe_grow_cleared (newlen);
+      for (unsigned i = len; i < newlen; i++)
+       type_warnings[i].dyn_count = profile_count::zero ();
+    }
+}
+
 struct final_warning_record *final_warning_records;
 
 /* Return vector containing possible targets of polymorphic call of type
@@ -3176,9 +3193,8 @@ possible_polymorphic_call_targets (tree otr_type,
                      && warn_suggest_final_types
                      && !outer_type->derived_types.length ())
                    {
-                     if (outer_type->id >= (int)final_warning_records->type_warnings.length ())
-                       final_warning_records->type_warnings.safe_grow_cleared
-                         (odr_types.length ());
+                     final_warning_records->grow_type_warnings
+                       (outer_type->id);
                      final_warning_records->type_warnings[outer_type->id].count++;
                      if (!final_warning_records->type_warnings
                                [outer_type->id].dyn_count.initialized_p ())
@@ -3545,8 +3561,7 @@ ipa_devirt (void)
     {
       final_warning_records = new (final_warning_record);
       final_warning_records->dyn_count = profile_count::zero ();
-      final_warning_records->type_warnings.safe_grow_cleared
-                                                (odr_types.length ());
+      final_warning_records->grow_type_warnings (odr_types.length ());
       free_polymorphic_call_targets_hash ();
     }
 
index cdd0ae2d42c70cec2e3b2de2e8f62e4b668197ba..3949efb2ccb7936795d9eb8cfa949edae7f502f3 100644 (file)
@@ -1,3 +1,8 @@
+2018-01-12  Martin Liska  <mliska@suse.cz>
+
+       PR ipa/83054
+       * g++.dg/warn/pr83054.C: New test.
+
 2018-01-11  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        * gcc.target/powerpc/spec-barr-1.c: New file.
diff --git a/gcc/testsuite/g++.dg/warn/pr83054.C b/gcc/testsuite/g++.dg/warn/pr83054.C
new file mode 100644 (file)
index 0000000..506c960
--- /dev/null
@@ -0,0 +1,41 @@
+// PR ipa/83054
+// { dg-options "-O3 -Wsuggest-final-types" }
+// { dg-do compile }
+
+extern "C" int printf (const char *, ...);
+struct foo // { dg-warning "final would enable devirtualization of 5 calls" }
+{
+  static int count;
+  void print (int i, int j) { printf ("foo[%d][%d] = %d\n", i, j, x); }
+  int x;
+  foo () {
+    x = count++;
+    printf("this %d = %x\n", x, (void *)this);
+  }
+  virtual ~foo () {
+    printf("this %d = %x\n", x, (void *)this);
+    --count;
+  }
+};
+int foo::count;
+
+
+int main ()
+{
+  {
+    foo array[3][3];
+    for (int i = 0; i < 3; i++)
+      {
+       for (int j = 0; j < 3; j++)
+         {
+           printf("&a[%d][%d] = %x\n", i, j, (void *)&array[i][j]);
+         }
+      }
+      // The count should be nine, if not, fail the test.
+      if (foo::count != 9)
+       return 1;
+  }
+  if (foo::count != 0)
+    return 1;
+  return 0;
+}