This is the mail archive of the gcc@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]

Re: aliasing warnings [patch]


Zack Weinberg wrote:
> 
> Hmm... well, check this patch out.  It isn't necessary to add another
> slot to every tree node, which is a relief.  It nails my test case
> dead on, but generates a pile of complaints about libgcc which I'm not
> sure if they're spurious or not yet.

Argh... patch riddled with bugs.  Try this one instead.  This gets rid
of all the spurious warnings from libgcc2.  It no longer warns about
the "foo1" case of the test program, but it was warning about that for
the wrong reason.

zw

Index: c-typeck.c
===================================================================
RCS file: /cvs/egcs/egcs/gcc/c-typeck.c,v
retrieving revision 1.39
diff -u -p -r1.39 c-typeck.c
--- c-typeck.c	1999/09/22 05:51:44	1.39
+++ c-typeck.c	1999/09/25 21:08:54
@@ -1217,6 +1217,7 @@ build_indirect_ref (ptr, errorstring)
       else
 	{
 	  tree t = TREE_TYPE (type);
+	  tree orig_t, field = 0;
 	  register tree ref = build1 (INDIRECT_REF,
 				      TYPE_MAIN_VARIANT (t), pointer);
 
@@ -1228,16 +1229,49 @@ build_indirect_ref (ptr, errorstring)
 	  if (TREE_CODE (t) == VOID_TYPE && skip_evaluation == 0)
 	    warning ("dereferencing `void *' pointer");
 
-	  /* We *must* set TREE_READONLY when dereferencing a pointer to const,
-	     so that we get the proper error message if the result is used
-	     to assign to.  Also, &* is supposed to be a no-op.
-	     And ANSI C seems to specify that the type of the result
-	     should be the const type.  */
-	  /* A de-reference of a pointer to const is not a const.  It is valid
-	     to change it via some other pointer.  */
+	  /* If we are dereferencing a pointer through a cast to some
+	     other type, check that the type of the pointer and the
+	     type of the object pointed to are compatible alias-wise.  */
+
+	  orig_t = pointer;
+	  while (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (orig_t))))
+	    orig_t = TREE_OPERAND (orig_t, 0);
+
+	  orig_t = TREE_TYPE (orig_t);
+	  /* Now peel off one layer of indirection from the type, if present.
+	     If the type is a function, first get its return type and
+	     then peel off one layer.  */
+	  if (TREE_CODE (orig_t) == FUNCTION_TYPE)
+	      orig_t = TREE_TYPE (orig_t);
+	  if (TREE_CODE (orig_t) == POINTER_TYPE)
+	      orig_t = TREE_TYPE (orig_t);
+
+	  if (TREE_CODE (t) == UNION_TYPE && !pedantic)
+	    {
+	      for (field = TYPE_FIELDS (t); field;
+		   field = TREE_CHAIN (field))
+		if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
+			       TYPE_MAIN_VARIANT (orig_t)))
+		  break;
+	    }
+
+	  if (!(get_alias_set (t) == get_alias_set (orig_t)
+		|| TYPE_MAIN_VARIANT (t) == char_type_node
+		|| TYPE_MAIN_VARIANT (orig_t) == char_type_node
+		|| TREE_CODE (orig_t) == VOID_TYPE || field))
+	    warning ("dereferencing pointer to type T which points at value of type U");
+	  
+	  /* We *must* set TREE_READONLY when dereferencing a pointer
+	     to const, so that we get the proper error message if the
+	     result is used to assign to.  Also, &* is supposed to be
+	     a no-op.  And ANSI C seems to specify that the type of
+	     the result should be the const type.  */
+	  /* A de-reference of a pointer to const is not a const.  It
+	     is valid to change it via some other pointer.  */
 	  TREE_READONLY (ref) = TYPE_READONLY (t);
 	  TREE_SIDE_EFFECTS (ref)
-	    = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile;
+	    = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer)
+	      || flag_volatile;
 	  TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
 	  return ref;
 	}

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