gcc/0137-DFE-Fix-unexpected-struct-function-pointer-eliminati.patch
2023-11-30 11:31:49 +08:00

118 lines
2.9 KiB
Diff

From 25d74b98caeaae881e374924886ee664aa1af5bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=83=91=E6=99=A8=E5=8D=89?= <zhengchenhui1@huawei.com>
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 <stdlib.h>
+#include <stdio.h>
+
+#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