118 lines
2.9 KiB
Diff
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
|
|
|