diff options
author | Richard Henderson <rth@redhat.com> | 2002-06-20 00:30:04 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2002-06-20 00:30:04 -0700 |
commit | 74d86f4fc1c5966e88f0cf977e33bb26c0cd643e (patch) | |
tree | 0c4e881b9c304c27324e19124ed29268823cef27 /gcc | |
parent | 3b4008995c857e733ea4d998f1228acacc13dafe (diff) | |
download | gcc-74d86f4fc1c5966e88f0cf977e33bb26c0cd643e.zip gcc-74d86f4fc1c5966e88f0cf977e33bb26c0cd643e.tar.gz gcc-74d86f4fc1c5966e88f0cf977e33bb26c0cd643e.tar.bz2 |
c-common.c (c_common_get_alias_set): Correctly handle characters.
* c-common.c (c_common_get_alias_set): Correctly handle characters.
Rearrange order of expressions; don't handle vectors here.
* alias.c (get_alias_set): Let vectors match their components.
From-SVN: r54821
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/alias.c | 8 | ||||
-rw-r--r-- | gcc/c-common.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20020619-1.c | 32 |
4 files changed, 56 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2a26702..710e2cd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2002-05-20 Richard Henderson <rth@redhat.com> + + * c-common.c (c_common_get_alias_set): Correctly handle characters. + Rearrange order of expressions; don't handle vectors here. + * alias.c (get_alias_set): Let vectors match their components. + 2002-06-19 Chris Demetriou <cgd@broadcom.com> * config/mips/mips.c (mips_emit_prefetch): Use hints which diff --git a/gcc/alias.c b/gcc/alias.c index d892926..2e6a2b0 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -575,6 +575,14 @@ get_alias_set (t) and references to functions, but that's different.) */ else if (TREE_CODE (t) == FUNCTION_TYPE) set = 0; + + /* Unless the language specifies otherwise, let vector types alias + their components. This avoids some nasty type punning issues in + normal usage. And indeed lets vectors be treated more like an + array slice. */ + else if (TREE_CODE (t) == VECTOR_TYPE) + set = get_alias_set (TREE_TYPE (t)); + else /* Otherwise make a new alias set for this type. */ set = new_alias_set (); diff --git a/gcc/c-common.c b/gcc/c-common.c index b477fe7..c71f752 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -2527,10 +2527,6 @@ c_common_get_alias_set (t) { tree u; - /* We know nothing about vector types */ - if (TREE_CODE (t) == VECTOR_TYPE) - 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 @@ -2544,21 +2540,21 @@ c_common_get_alias_set (t) && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) return 0; - /* If this is a char *, the ANSI C standard says it can alias - anything. Note that all references need do this. */ - if (TREE_CODE_CLASS (TREE_CODE (t)) == 'r' - && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE - && TYPE_PRECISION (TREE_TYPE (t)) == TYPE_PRECISION (char_type_node)) + /* That's all the expressions we handle specially. */ + if (! TYPE_P (t)) + return -1; + + /* The C standard guarantess that any object may be accessed via an + lvalue that has character type. */ + if (t == char_type_node + || t == signed_char_type_node + || t == unsigned_char_type_node) return 0; /* If it has the may_alias attribute, it can alias anything. */ - if (TYPE_P (t) && lookup_attribute ("may_alias", TYPE_ATTRIBUTES (t))) + if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (t))) return 0; - /* That's all the expressions we handle specially. */ - if (! TYPE_P (t)) - return -1; - /* The C standard specifically allows aliasing between signed and unsigned variants of the same type. We treat the signed variant as canonical. */ diff --git a/gcc/testsuite/gcc.c-torture/execute/20020619-1.c b/gcc/testsuite/gcc.c-torture/execute/20020619-1.c new file mode 100644 index 0000000..5ed4d00 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20020619-1.c @@ -0,0 +1,32 @@ +static int ref(void) +{ + union { + char c[5]; + int i; + } u; + + __builtin_memset (&u, 0, sizeof(u)); + u.c[0] = 1; + u.c[1] = 2; + u.c[2] = 3; + u.c[3] = 4; + + return u.i; +} + +#define MAX(a,b) (a < b ? b : a) + +static int test(void) +{ + char c[MAX(5, sizeof(int))] __attribute__((aligned)) = { 1, 2, 3, 4 }; + return *(int *)c; +} + +int main() +{ + int a = test(); + int b = ref(); + if (a != b) + abort (); + return 0; +} |