diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-10-31 20:44:46 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-10-31 20:44:46 +0000 |
commit | be4f2de7f301344014ad17f9904ec1c03e5d7372 (patch) | |
tree | 86c2bd76ff3b4b065432438c38694e48e5a6b8f5 | |
parent | 5b5a733afd1676a4974c023951b6d9d9e5cab029 (diff) | |
download | ppe42-gcc-be4f2de7f301344014ad17f9904ec1c03e5d7372.tar.gz ppe42-gcc-be4f2de7f301344014ad17f9904ec1c03e5d7372.zip |
�
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@23481 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/c-common.c | 38 |
1 files changed, 22 insertions, 16 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index c9023585f3c..f45b5662020 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -3135,6 +3135,7 @@ c_get_alias_set (t) tree t; { tree type; + tree u; if (t == error_mark_node) return 0; @@ -3155,22 +3156,18 @@ c_get_alias_set (t) the conservative assumption. */ return 0; - if ((TREE_CODE (t) == COMPONENT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_TYPE) - /* Also permit punning when accessing an array which is a union - member. This makes the current sparc va_arg macro work, but may - not be otherwise necessary. */ - || (TREE_CODE (t) == ARRAY_REF - && TREE_CODE (TREE_OPERAND (t, 0)) == COMPONENT_REF - && (TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (t, 0), 0))) - == UNION_TYPE))) - /* Permit type-punning when accessing a union, provided the - access is directly through the union. For example, this code does - not permit taking the address of a union member and then - 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; + /* Permit type-punning when accessing a union, provided the access + is directly through the union. For example, this code does not + permit taking the address of a union member and then 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. */ + for (u = t; + TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF; + u = TREE_OPERAND (u, 0)) + if (TREE_CODE (u) == COMPONENT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) + return 0; if (TREE_CODE (t) == INDIRECT_REF) { @@ -3184,6 +3181,15 @@ c_get_alias_set (t) /* 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 we've already calculated the value, just return it. */ return TYPE_ALIAS_SET (type); |