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 26626


This fixes PR26626, where we got a bit too aggressive in deciding what
variables accesses can point to, particularly when typecasting through
union pointers.

At the same time, it discovered a few bugs in the heuristic that decides
whether we need to solve the points-to graph, so i've turned it off for
now, while we work through the problems.


Bootstrapped and regtested on i686-pc-linux-gnu.
Committed to mainline.

2006-05-02  Daniel Berlin  <dberlin@dberlin.org>

	Fix PR tree-optimization/26626
	* tree-ssa-structalias.c (compute_points_to_sets): For now, solve
	always.
	* tree-ssa-operands.c (access_can_touch_variable): Allow
	typecasting through union pointers.

Index: tree-ssa-structalias.c
===================================================================
--- tree-ssa-structalias.c	(revision 113323)
+++ tree-ssa-structalias.c	(working copy)
@@ -4485,7 +4485,7 @@ compute_points_to_sets (struct alias_inf
       dump_constraints (dump_file);
     }
   
-  if (need_to_solve ())
+  if (1 || need_to_solve ())
     {
       if (dump_file)
 	fprintf (dump_file,
Index: tree-ssa-operands.c
===================================================================
--- tree-ssa-operands.c	(revision 113323)
+++ tree-ssa-operands.c	(working copy)
@@ -1118,11 +1118,32 @@ access_can_touch_variable (tree ref, tre
      { return (struct foos *)&foo; }
      
      (taken from 20000623-1.c)
+
+     The docs also say/imply that access through union pointers
+     is legal (but *not* if you take the address of the union member,
+     i.e. the inverse), such that you can do
+
+     typedef union {
+       int d;
+     } U;
+
+     int rv;
+     void breakme()
+     {
+       U *rv0;
+       U *pretmp = (U*)&rv;
+       rv0 = pretmp;
+       rv0->d = 42;    
+     }
+     To implement this, we just punt on accesses through union
+     pointers entirely.
   */
   else if (ref 
 	   && flag_strict_aliasing
 	   && TREE_CODE (ref) != INDIRECT_REF
 	   && !MTAG_P (alias)
+	   && (TREE_CODE (base) != INDIRECT_REF
+	       || TREE_CODE (TREE_TYPE (base)) != UNION_TYPE)
 	   && !AGGREGATE_TYPE_P (TREE_TYPE (alias))
 	   && TREE_CODE (TREE_TYPE (alias)) != COMPLEX_TYPE
 	   && !POINTER_TYPE_P (TREE_TYPE (alias)))
Index: testsuite/gcc.c-torture/compile/pr26626.c
===================================================================
--- testsuite/gcc.c-torture/compile/pr26626.c   (revision 0)
+++ testsuite/gcc.c-torture/compile/pr26626.c   (revision 0)
@@ -0,0 +1,13 @@
+typedef union {
+    int d;
+} U;
+
+int rv;
+void breakme()
+{
+    U *rv0;
+    U *pretmp = (U*)&rv;
+    rv0 = pretmp;
+    rv0->d = 42;
+}
+

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