Hi.

There's an example of zero initialized profile_count. Instead I guess we want
to initialize it to profile_count::zero.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.

Ready to be installed?
Martin
>From 0cb1501005429cc7ef1083bfc279d7be2a6197aa Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Wed, 10 Jan 2018 15:30:33 +0100
Subject: [PATCH] Initialize type_warnings::dyn_count with a default value (PR
 ipa/83054).

gcc/ChangeLog:

2018-01-10  Martin Liska  <mli...@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.

gcc/testsuite/ChangeLog:

2018-01-10  Martin Liska  <mli...@suse.cz>

	* g++.dg/warn/pr83054.C: New test.
---
 gcc/ipa-devirt.c                    | 25 +++++++++++++++++-----
 gcc/testsuite/g++.dg/warn/pr83054.C | 41 +++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/pr83054.C

diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 8de004fef63..cc551d636fd 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -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 ();
     }
 
diff --git a/gcc/testsuite/g++.dg/warn/pr83054.C b/gcc/testsuite/g++.dg/warn/pr83054.C
new file mode 100644
index 00000000000..506c9609b90
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/pr83054.C
@@ -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;
+}
-- 
2.14.3

Reply via email to