This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH]: Fix PR tree-optimization/21839
- From: Daniel Berlin <dberlin at dberlin dot org>
- To: Diego Novillo <dnovillo at redhat dot com>, GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 31 May 2005 14:42:42 -0400
- Subject: [PATCH]: Fix PR tree-optimization/21839
This bug is a result of the empty structure extension.
The gimplifier decides to emit 0 initializations for the 0-sized field
"lock" in something like:
typedef struct { } spinlock_t;
typedef struct {
unsigned sequence;
spinlock_t lock;
} seqlock_t;
void ext3_new_inode(seqlock_t *rsv_seqlock)
{
*rsv_seqlock = (seqlock_t) { 0, (spinlock_t) { } };
}
so we get
D.1246.lock = 0
salias decides the field is not in the used portion of the structure
(because it isn't), so doesn't create a subvar for it.
Then verify_ssa complains because it thinks D.1246.lock = 0 is a memory
store with a may_def/must_def.
Theoretically, both are right.
D.1246.lock = 0 doesn't cause any more or less of the "seqlock_t"
structure to be used, because it has no size, and it isn't in the used
portion of the structure, because it's a store to offset 32 of size 0,
and we already thought that 0,32 was used. Thus salias is correct in
not creating a 0-sized subvar for this.
D.1246.lock = 0 could also be considered a memory store, even though
it's a zero sized one.
But to know what it means, we'd have to answer the zen question "What
does a store to a zero sized field do?".
After meditating on a rock for a few hours, i decided the best solution
to this problem is to teach the gimplifier not to emit sets for the 0
sized fields, in order to prevent my brain from exploding.
Bootstrapped and regtested on i686-pc-linux-gnu (without java, gcjh is
getting miscompiled since 920501-2.c started failing, on all my clean
trees :()
Okay for mainline?
--Dan
2005-05-30 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/21839
* gimplify.c (zero_sized_field_decl): New function.
(gimplify_init_ctor_eval): Use it.
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gimplify.c,v
retrieving revision 2.128
diff -u -p -r2.128 gimplify.c
--- gimplify.c 27 May 2005 17:23:29 -0000 2.128
+++ gimplify.c 31 May 2005 18:15:26 -0000
@@ -2505,6 +2505,14 @@ gimplify_init_ctor_eval_range (tree obje
pre_p);
}
+/* Return true if ref is accessing a field that is zero sized. */
+
+static bool
+zero_sized_field_decl (tree fdecl)
+{
+ return DECL_SIZE (fdecl) && integer_zerop (DECL_SIZE (fdecl));
+}
+
/* A subroutine of gimplify_init_constructor. Generate individual
MODIFY_EXPRs for a CONSTRUCTOR. OBJECT is the LHS against which the
assignments should happen. LIST is the CONSTRUCTOR_ELTS of the
@@ -2537,6 +2545,9 @@ gimplify_init_ctor_eval (tree object, tr
so we don't have to figure out what's missing ourselves. */
gcc_assert (purpose);
+ if (zero_sized_field_decl (purpose))
+ continue;
+
/* If we have a RANGE_EXPR, we have to build a loop to assign the
whole range. */
if (TREE_CODE (purpose) == RANGE_EXPR)
Index: testsuite/gcc.c-torture/compile/pr21839.c
===================================================================
RCS file: testsuite/gcc.c-torture/compile/pr21839.c
diff -N testsuite/gcc.c-torture/compile/pr21839.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.c-torture/compile/pr21839.c 31 May 2005 18:15:30 -0000
@@ -0,0 +1,12 @@
+ typedef struct { } spinlock_t;
+typedef struct {
+ unsigned sequence;
+ spinlock_t lock;
+} seqlock_t;
+void ext3_new_inode(seqlock_t *rsv_seqlock)
+{
+ *rsv_seqlock = (seqlock_t) { 0, (spinlock_t) { } };
+
+}
+
+