+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
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
&& 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 ())
{
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 ();
}
--- /dev/null
+// 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;
+}