c-common.c (c_get_alias_set): Allow all type-punning through unions.
� * c-common.c (c_get_alias_set): Allow all type-punning through unions. Don't get confused about the type of a bit-field, despite the antics of build_modify_expr. From-SVN: r23481
This commit is contained in:
parent
43d8a6c79f
commit
08bc243195
@ -3135,6 +3135,7 @@ c_get_alias_set (t)
|
|||||||
tree t;
|
tree t;
|
||||||
{
|
{
|
||||||
tree type;
|
tree type;
|
||||||
|
tree u;
|
||||||
|
|
||||||
if (t == error_mark_node)
|
if (t == error_mark_node)
|
||||||
return 0;
|
return 0;
|
||||||
@ -3155,22 +3156,18 @@ c_get_alias_set (t)
|
|||||||
the conservative assumption. */
|
the conservative assumption. */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ((TREE_CODE (t) == COMPONENT_REF
|
/* Permit type-punning when accessing a union, provided the access
|
||||||
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE)
|
is directly through the union. For example, this code does not
|
||||||
/* Also permit punning when accessing an array which is a union
|
permit taking the address of a union member and then storing
|
||||||
member. This makes the current sparc va_arg macro work, but may
|
through it. Even the type-punning allowed here is a GCC
|
||||||
not be otherwise necessary. */
|
extension, albeit a common and useful one; the C standard says
|
||||||
|| (TREE_CODE (t) == ARRAY_REF
|
that such accesses have implementation-defined behavior. */
|
||||||
&& TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF
|
for (u = t;
|
||||||
&& (TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
|
TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
|
||||||
== UNION_TYPE)))
|
u = TREE_OPERAND (u, 0))
|
||||||
/* Permit type-punning when accessing a union, provided the
|
if (TREE_CODE (u) == COMPONENT_REF
|
||||||
access is directly through the union. For example, this code does
|
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
|
||||||
not permit taking the address of a union member and then
|
return 0;
|
||||||
storing through it. Even the type-punning allowed here is a
|
|
||||||
GCC extension, albeit a common and useful one; the C standard
|
|
||||||
says that such accesses have implementation-defined behavior. */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (TREE_CODE (t) == INDIRECT_REF)
|
if (TREE_CODE (t) == INDIRECT_REF)
|
||||||
{
|
{
|
||||||
@ -3184,6 +3181,15 @@ c_get_alias_set (t)
|
|||||||
|
|
||||||
/* From here on, only the type matters. */
|
/* From here on, only the type matters. */
|
||||||
|
|
||||||
|
if (TREE_CODE (t) == COMPONENT_REF
|
||||||
|
&& DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)))
|
||||||
|
/* Since build_modify_expr calls get_unwidened for stores to
|
||||||
|
component references, the type of a bit field can be changed
|
||||||
|
from (say) `unsigned int : 16' to `unsigned short' or from
|
||||||
|
`enum E : 16' to `short'. We want the real type of the
|
||||||
|
bit-field in this case, not some the integral equivalent. */
|
||||||
|
type = DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1));
|
||||||
|
|
||||||
if (TYPE_ALIAS_SET_KNOWN_P (type))
|
if (TYPE_ALIAS_SET_KNOWN_P (type))
|
||||||
/* If we've already calculated the value, just return it. */
|
/* If we've already calculated the value, just return it. */
|
||||||
return TYPE_ALIAS_SET (type);
|
return TYPE_ALIAS_SET (type);
|
||||||
|
Loading…
Reference in New Issue
Block a user