From 25d74b98caeaae881e374924886ee664aa1af5bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=83=91=E6=99=A8=E5=8D=89?= Date: Mon, 9 Oct 2023 14:41:01 +0800 Subject: [PATCH 22/26] [DFE]Fix unexpected struct function pointer elimination bug. --- gcc/ipa-struct-reorg/ipa-struct-reorg.c | 9 ++- gcc/testsuite/gcc.dg/struct/dfe_func_ptr.c | 69 ++++++++++++++++++++++ 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/struct/dfe_func_ptr.c diff --git a/gcc/ipa-struct-reorg/ipa-struct-reorg.c b/gcc/ipa-struct-reorg/ipa-struct-reorg.c index 367bcf210..fe99e8733 100644 --- a/gcc/ipa-struct-reorg/ipa-struct-reorg.c +++ b/gcc/ipa-struct-reorg/ipa-struct-reorg.c @@ -438,7 +438,11 @@ srtype::has_dead_field (void) unsigned i; FOR_EACH_VEC_ELT (fields, i, this_field) { - if (!(this_field->field_access & READ_FIELD)) + /* Function pointer members are not processed, because DFE + does not currently support accurate analysis of function + pointers, and we have not identified specific use cases. */ + if (!(this_field->field_access & READ_FIELD) + && !FUNCTION_POINTER_TYPE_P (this_field->fieldtype)) { may_dfe = true; break; @@ -1024,7 +1028,8 @@ srtype::create_new_type (void) { srfield *f = fields[i]; if (current_layout_opt_level & DEAD_FIELD_ELIMINATION - && !(f->field_access & READ_FIELD)) + && !(f->field_access & READ_FIELD) + && !FUNCTION_POINTER_TYPE_P (f->fieldtype)) continue; f->create_new_fields (newtype, newfields, newlast); } diff --git a/gcc/testsuite/gcc.dg/struct/dfe_func_ptr.c b/gcc/testsuite/gcc.dg/struct/dfe_func_ptr.c new file mode 100644 index 000000000..74ea93bbc --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct/dfe_func_ptr.c @@ -0,0 +1,69 @@ +/* { dg-do compile } */ +/* { dg-do run } */ + +#include +#include + +#ifdef STACK_SIZE +#if STACK_SIZE > 16000 +#define N 1000 +#else +#define N (STACK_SIZE/16) +#endif +#else +#define N 1000 +#endif + +int num; + +int (*foo)(int d); +int f (int t); + +typedef struct str_t str_t1; +struct str_t +{ + int a; + float b; + int (*foo)(int d); +}; + +int main () +{ + int i, r; + r = rand (); + num = r > N ? N : r; + str_t1 * p1 = calloc (num, sizeof (str_t1)); + if (p1 == NULL) + return 0; + for (i = 0; i < num; i++) + { + p1[i].foo = malloc (1 * sizeof (f)); + p1[i].foo = f; + p1[i].foo (i); + } + + for (i = 0; i < num; i++) + p1[i].a = 1; + + for (i = 0; i < num; i++) + p1[i].b = 2; + + for (i = 0; i < num; i++) + if (p1[i].a != 1) + abort (); + + for (i = 0; i < num; i++) + if (abs (p1[i].b - 2) > 0.0001) + abort (); + + return 0; +} + +int f (int t) +{ + if ( t < 0) + abort (); + return 0; +} + +/* { dg-final { scan-ipa-dump-times "Dead field elimination" 0 "struct_reorg" } } */ -- 2.27.0