Bug 42136 - Inconsistent strict-aliasing warning with cast from char[]
Summary: Inconsistent strict-aliasing warning with cast from char[]
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.5.0
: P3 enhancement
Target Milestone: 7.2
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2009-11-21 22:48 UTC by astrange+gcc@gmail.com
Modified: 2021-11-28 04:06 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 7.2.0, 8.1.0
Known to fail: 7.1.0
Last reconfirmed: 2009-11-21 22:56:31


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description astrange+gcc@gmail.com 2009-11-21 22:48:04 UTC
Source:
typedef union u { unsigned i; unsigned short s[2]; unsigned char c[4]; } u;

char c[4] __attribute__((aligned));
short s[2] __attribute__((aligned));

int f1()
{
	return ((union u*)s)->i;
}

int f2()
{
	return ((union u*)c)->i;
}

Using gcc 4.5:

> gcc -O3 -fstrict-aliasing -Wall -S wstrict_aliasing_char.c

wstrict_aliasing_char.c: In function 'f2':
wstrict_aliasing_char.c:13:17: warning: dereferencing type-punned pointer will break strict-aliasing rules

I would expect either both or neither of the functions to warn, since pointer casting to unions is given in the manual as something that violates strict-aliasing, although gcc doesn't seem to actually take advantage of this.

Instead, it looks like the warning is hardcoded to apply to a cast from char (c-common.c:1746 in r1554411):
          alias_set_type set1 =
	    get_alias_set (TREE_TYPE (TREE_OPERAND (expr, 0)));
          alias_set_type set2 = get_alias_set (TREE_TYPE (type));

          if (set1 != set2 && set2 != 0
	      && (set1 == 0 || !alias_sets_conflict_p (set1, set2)))
	    {
	      warning (OPT_Wstrict_aliasing, "dereferencing type-punned "
		       "pointer will break strict-aliasing rules");
	      return true;
	    }

This came up during some x264 work, but it's taken care of now with some __attribute__((may_alias)).
Comment 1 Richard Biener 2009-11-21 22:56:31 UTC
!alias_sets_conflict_p (set1, set2) should really be alias_set_subset_of
with all the added false positives from the very imprecise frontend code
that this would cause.

Thus, the cast from short[] also should warn.
Comment 2 Andrew Pinski 2021-11-28 04:06:43 UTC
Fixed in GCC 7.2.0 and above by the patch which fixed PR 80593.