public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* -fstrict-aliasing, -Wstrict-aliasing=2, and indirect conversions
@ 2005-07-26 23:52 Harald van Dijk
  2005-07-27  2:37 ` Ian Lance Taylor
  0 siblings, 1 reply; 5+ messages in thread
From: Harald van Dijk @ 2005-07-26 23:52 UTC (permalink / raw)
  To: gcc-help

Hello,

int main() {
     int a = 1;
     short *b = (short *) (char *) &a;
     *b = 2;
     return a;
}

This simple program returns 1 when compiled with -O2 -fstrict-aliasing, 
and 2 when compiled with -O2 -fno-strict-aliasing. It does not produce 
any warnings with -Wstrict-aliasing=2. According to the documentation:

`-Wstrict-aliasing=2'
      This option is only active when `-fstrict-aliasing' is active.  It
      warns about all code which might break the strict aliasing rules
      that the compiler is using for optimization.  This warning catches
      all cases, but it will also give a warning for some ambiguous
      cases that are safe.

Is this a bug? If so, what is the bug? Is the warning missing, or is the 
optimization invalid? And are there any alternative options that really 
catch every aliasing problem?

I'm using gcc 4.0.1 on i686-pc-linux-gnu.

Thanks in advance for any replies.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: -fstrict-aliasing, -Wstrict-aliasing=2, and indirect conversions
  2005-07-26 23:52 -fstrict-aliasing, -Wstrict-aliasing=2, and indirect conversions Harald van Dijk
@ 2005-07-27  2:37 ` Ian Lance Taylor
  2005-07-27 21:17   ` Harald van Dijk
  0 siblings, 1 reply; 5+ messages in thread
From: Ian Lance Taylor @ 2005-07-27  2:37 UTC (permalink / raw)
  To: Harald van Dijk; +Cc: gcc-help, gcc-patches

Harald van Dijk <truedfx@gentoo.org> writes:

> int main() {
>      int a = 1;
>      short *b = (short *) (char *) &a;
>      *b = 2;
>      return a;
> }
> 
> This simple program returns 1 when compiled with -O2
> -fstrict-aliasing, and 2 when compiled with -O2
> -fno-strict-aliasing. It does not produce any warnings with
> -Wstrict-aliasing=2. According to the documentation:
> 
> `-Wstrict-aliasing=2'
>       This option is only active when `-fstrict-aliasing' is active.  It
>       warns about all code which might break the strict aliasing rules
>       that the compiler is using for optimization.  This warning catches
>       all cases, but it will also give a warning for some ambiguous
>       cases that are safe.
> 
> Is this a bug? If so, what is the bug? Is the warning missing, or is
> the optimization invalid? And are there any alternative options that
> really catch every aliasing problem?

There should be a warning here.  The warning code is confused by the
double cast.  If you cast directly to short *, you should get the
warning.

I'm going to test this patch to fix this problem.  Anybody see
anything wrong with it?

Ian


2005-07-26  Ian Lance Taylor  <ian@airs.com>

	* c-typeck.c (build_c_cast): For warn_strict_aliasing warnings,
	use STRIP_NOPS on the operand.


Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.467
diff -p -c -r1.467 c-typeck.c
*** c-typeck.c	20 Jul 2005 01:18:06 -0000	1.467
--- c-typeck.c	27 Jul 2005 02:36:51 -0000
*************** build_c_cast (tree type, tree expr)
*** 3306,3334 ****
  
        if (flag_strict_aliasing && warn_strict_aliasing
  	  && TREE_CODE (type) == POINTER_TYPE
! 	  && TREE_CODE (otype) == POINTER_TYPE
! 	  && TREE_CODE (expr) == ADDR_EXPR
! 	  && (DECL_P (TREE_OPERAND (expr, 0))
! 	      || TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF)
! 	  && !VOID_TYPE_P (TREE_TYPE (type)))
! 	{
! 	  /* Casting the address of an object to non void pointer. Warn
! 	     if the cast breaks type based aliasing.  */
! 	  if (!COMPLETE_TYPE_P (TREE_TYPE (type)))
! 	    warning (OPT_Wstrict_aliasing, "type-punning to incomplete type "
! 		     "might break strict-aliasing rules");
! 	  else
! 	    {
! 	      HOST_WIDE_INT set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
! 	      HOST_WIDE_INT set2 = get_alias_set (TREE_TYPE (type));
  
! 	      if (!alias_sets_conflict_p (set1, set2))
! 		warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
! 			 "pointer will break strict-aliasing rules");
! 	      else if (warn_strict_aliasing > 1
! 		       && !alias_sets_might_conflict_p (set1, set2))
! 		warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
! 			 "pointer might break strict-aliasing rules");
  	    }
  	}
  
--- 3306,3341 ----
  
        if (flag_strict_aliasing && warn_strict_aliasing
  	  && TREE_CODE (type) == POINTER_TYPE
! 	  && TREE_CODE (otype) == POINTER_TYPE)
! 	{
! 	  tree e = expr;
  
! 	  STRIP_NOPS (e);
! 	  if (TREE_CODE (e) == ADDR_EXPR
! 	      && (DECL_P (TREE_OPERAND (e, 0))
! 		  || TREE_CODE (TREE_OPERAND (e, 0)) == COMPONENT_REF)
! 	      && !VOID_TYPE_P (TREE_TYPE (type)))
! 	    {
! 	      /* Casting the address of an object to non void pointer.
! 		 Warn if the cast breaks type based aliasing.  */
! 	      if (!COMPLETE_TYPE_P (TREE_TYPE (type)))
! 		warning (OPT_Wstrict_aliasing,
! 			 "type-punning to incomplete type "
! 			 "might break strict-aliasing rules");
! 	      else
! 		{
! 		  HOST_WIDE_INT set1, set2;
! 
! 		  set1 = get_alias_set (TREE_TYPE (TREE_OPERAND (e, 0)));
! 		  set2 = get_alias_set (TREE_TYPE (type));
! 		  if (!alias_sets_conflict_p (set1, set2))
! 		    warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
! 			     "pointer will break strict-aliasing rules");
! 		  else if (warn_strict_aliasing > 1
! 			   && !alias_sets_might_conflict_p (set1, set2))
! 		    warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
! 			     "pointer might break strict-aliasing rules");
! 		}
  	    }
  	}
  

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: -fstrict-aliasing, -Wstrict-aliasing=2, and indirect conversions
  2005-07-27  2:37 ` Ian Lance Taylor
@ 2005-07-27 21:17   ` Harald van Dijk
  2005-07-27 22:23     ` Ian Lance Taylor
  0 siblings, 1 reply; 5+ messages in thread
From: Harald van Dijk @ 2005-07-27 21:17 UTC (permalink / raw)
  To: gcc-help

Ian Lance Taylor wrote:
> There should be a warning here.  The warning code is confused by the
> double cast.  If you cast directly to short *, you should get the
> warning.
> 
> I'm going to test this patch to fix this problem.  Anybody see
> anything wrong with it?

Hi,

Thank you for your quick reply. Your patch has been very helpful. It 
doesn't seem to catch these similar cases, though:

int main() {
     int a = 1;

     void *p1 = (void *) &a;
     * (short *) p1 = 2;

     char *p2 = (char *) &a;
     * (short *) p2 = 3;

     return a;
}

This still returns 1 without a warning. (I am now using 4.1.0-20050723, 
so that I could try your patch.)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: -fstrict-aliasing, -Wstrict-aliasing=2, and indirect conversions
  2005-07-27 21:17   ` Harald van Dijk
@ 2005-07-27 22:23     ` Ian Lance Taylor
  2005-07-27 23:53       ` Harald van Dijk
  0 siblings, 1 reply; 5+ messages in thread
From: Ian Lance Taylor @ 2005-07-27 22:23 UTC (permalink / raw)
  To: Harald van Dijk; +Cc: gcc-help

Harald van Dijk <truedfx@gentoo.org> writes:

> Thank you for your quick reply. Your patch has been very helpful. It
> doesn't seem to catch these similar cases, though:
> 
> int main() {
>      int a = 1;
> 
>      void *p1 = (void *) &a;
>      * (short *) p1 = 2;
> 
>      char *p2 = (char *) &a;
>      * (short *) p2 = 3;
> 
>      return a;
> }
> 
> This still returns 1 without a warning. (I am now using
> 4.1.0-20050723, so that I could try your patch.)

That is true.  I'm frankly not too sure what should be done.  If we
enable the warnings for these cases, the effect will be to warn about
almost every type cast which is not to or from void* or char*.  That
doesn't seem very useful.  On the other hand strict aliasing is a
serious problem.

Perhaps the problem is that the warning currently triggers on the
cast, but should perhaps somehow trigger on the dereference.  I think
the bug occurs if you have these statements:
    P2 = (TYPE *) P1;
    *P1;
    *P2;
in some order in the same function.  However, I don't know whether the
compiler has the data structures we would need to efficiently
determine whether this happens.

Could you please open a bugzilla PR for this at
http://gcc.gnu.org/bugzilla/ ?  That way at least the issue will get
recorded.  Thanks.

Ian

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: -fstrict-aliasing, -Wstrict-aliasing=2, and indirect conversions
  2005-07-27 22:23     ` Ian Lance Taylor
@ 2005-07-27 23:53       ` Harald van Dijk
  0 siblings, 0 replies; 5+ messages in thread
From: Harald van Dijk @ 2005-07-27 23:53 UTC (permalink / raw)
  To: gcc-help

Ian Lance Taylor wrote:
> Could you please open a bugzilla PR for this at
> http://gcc.gnu.org/bugzilla/ ?  That way at least the issue will get
> recorded.  Thanks.

Okay, reported as http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23106

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-07-27 23:53 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-26 23:52 -fstrict-aliasing, -Wstrict-aliasing=2, and indirect conversions Harald van Dijk
2005-07-27  2:37 ` Ian Lance Taylor
2005-07-27 21:17   ` Harald van Dijk
2005-07-27 22:23     ` Ian Lance Taylor
2005-07-27 23:53       ` Harald van Dijk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).