From 53b735889886371868daa0596ab14250eb71f6d6 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Fri, 12 Jan 2018 09:59:52 +0100 Subject: [PATCH] Initialize type_warnings::dyn_count with a default value (PR ipa/83054). 2018-01-12 Martin Liska 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 PR ipa/83054 * g++.dg/warn/pr83054.C: New test. From-SVN: r256566 --- gcc/ChangeLog | 8 ++++++ gcc/ipa-devirt.c | 25 ++++++++++++++---- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/warn/pr83054.C | 41 +++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/warn/pr83054.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3dff3ed65ce..5ed1111f9bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-01-12 Martin Liska + + 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 * profile-count.h (enum profile_quality): Use 0 as invalid 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 type_warnings; hash_map 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/ChangeLog b/gcc/testsuite/ChangeLog index cdd0ae2d42c..3949efb2ccb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-01-12 Martin Liska + + PR ipa/83054 + * g++.dg/warn/pr83054.C: New test. + 2018-01-11 Bill Schmidt * 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 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.30.2