This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH]: Fix PR tree-optimization/20489


This is code that i have plans to rewrite, sometime in the next week
(I've got a patch coming to make the verifier verify SFT's first).

When creating SFT's for nested structures, to avoid creating two SFT's
for offset 0 (one the containing structure, one for the first field) in
a structure, we weren't pushing the field onto the field list.
This doesn't work when the structure is empty, which is allowed in C++.

In the testcase here, we end up trying to take the address of a field
member we haven't created an SFT for, and bad things happen (I also have
plans to verify that we created the right number of SFT's for a type,
but this is a bit trickier).

We can't just push both and try to sort it out later, because we don't
know whether we are in a union or not (and if we are, it's perfectly
okay to have multiple fields at the same offset).

This patch makes the code check to see whether the structure we tried to
recurse into ended up being empty, and if so, we just push the original
field onto the field list.


Bootstrapped and regtested on i686-pc-linux-gnu.
Okay for mainline?
 --Dan
2005-03-15  Daniel Berlin  <dberlin@dberlin.org>
	
	Fix PR tree-optimiation/20489

	* tree-ssa-alias.c (push_fields_onto_fieldstack): DTRT
	for empty structures.
Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v
retrieving revision 2.74
diff -u -p -r2.74 tree-ssa-alias.c
--- tree-ssa-alias.c	13 Mar 2005 00:45:53 -0000	2.74
+++ tree-ssa-alias.c	16 Mar 2005 15:55:02 -0000
@@ -2729,8 +2729,21 @@ push_fields_onto_fieldstack (tree type, 
 	continue;
       if (var_can_have_subvars (field))
 	{
+	  size_t before = VEC_length (fieldoff_t, *fieldstack);
 	  push_fields_onto_fieldstack (TREE_TYPE (field), fieldstack, 
 				       offset + bitpos_of_field (field));
+      /* Empty structures may have actual size, like in C++. So see if we
+	 actually end up pushing a field, and if not, if the size is non-zero,
+	 push the field onto the stack */
+	  if (before == VEC_length (fieldoff_t, *fieldstack)
+	      && DECL_SIZE (field)
+	      && !integer_zerop (DECL_SIZE (field)))
+	    {
+	      pair = xmalloc (sizeof (struct fieldoff));
+	      pair->field = field;
+	      pair->offset = offset + bitpos_of_field (field);
+	      VEC_safe_push (fieldoff_t, *fieldstack, pair);
+	    }
 	}
       else
 	{
Index: testsuite/g++.dg/tree-ssa/pr20489.C
===================================================================
RCS file: testsuite/g++.dg/tree-ssa/pr20489.C
diff -N testsuite/g++.dg/tree-ssa/pr20489.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/tree-ssa/pr20489.C	16 Mar 2005 15:55:05 -0000
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct A
+{
+	~A();
+};
+
+/* If we don't create SFT's for the "empty" structure A, bad things
+   will happen, and we will fail verification.  */
+struct B
+{
+	int i;
+	A a;
+
+	void foo() {}
+};
+
+void bar()
+{
+	B().foo();
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]