This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix PR71598, aliasing between enums and compatible types
On March 15, 2019 3:39:16 PM GMT+01:00, Michael Matz <matz@suse.de> wrote:
>Hi,
>
>On Fri, 15 Mar 2019, Richard Biener wrote:
>
>> The following is an attempt to fix PR71598 where C (and C++?) have an
>
>> implementation-defined compatible integer type for each enum and the
>> TBAA rules mandate that accesses using a compatible type are allowed.
>
>But different enums aren't compatible with each other (or are they?),
>while your fix simply gives enums the aliasing set of the underlying
>type,
>i.e. makes all of them alias with each other. That's quite
>conservative.
But that follows from the need to be able to access an enum as int and the other way around. So both alias sets need to be subsets of each other which means they need to be equal.
Richard.
>
>Ciao,
>Michael.
>
>>
>> The fix is applied to all C family frontends and the LTO frontend
>> but not Fortran, Ada or other languages.
>>
>> Bootstrap & regtest running on x86_64-unknown-linux-gnu.
>>
>> I've tried to cover most cases even those with -fshort-enums.
>>
>> OK for trunk?
>>
>> It's probably a regression to some ancient GCC that didn't
>> perform TBAA and given it's wrong-code a backport is probably
>> mandated - do you agree? (after a while with no reported issues,
>> of course)
>>
>> Thanks,
>> Richard.
>>
>> 2019-03-15 Richard Biener <rguenther@suse.de>
>>
>> PR c/71598
>> * gimple.c: Include langhooks.h.
>> (gimple_get_alias_set): Treat enumeral types as the underlying
>> integer type.
>>
>> c-family/
>> * c-common.c (c_common_get_alias_set): Treat enumeral types
>> as the underlying integer type.
>>
>> * c-c++-common/torture/pr71598-1.c: New testcase.
>> * c-c++-common/torture/pr71598-2.c: Likewise.
>>
>> Index: gcc/gimple.c
>> ===================================================================
>> --- gcc/gimple.c (revision 269704)
>> +++ gcc/gimple.c (working copy)
>> @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.
>> #include "stringpool.h"
>> #include "attribs.h"
>> #include "asan.h"
>> +#include "langhooks.h"
>>
>>
>> /* All the tuples have their operand vector (if present) at the very
>bottom
>> @@ -2587,6 +2588,16 @@ gimple_get_alias_set (tree t)
>> return get_alias_set (t1);
>> }
>>
>> + /* Allow aliasing between enumeral types and the underlying
>> + integer type. This is required for C since those are
>> + compatible types. */
>> + else if (TREE_CODE (t) == ENUMERAL_TYPE)
>> + {
>> + tree t1 = lang_hooks.types.type_for_size (tree_to_uhwi
>(TYPE_SIZE (t)),
>> + false /* short-cut above */);
>> + return get_alias_set (t1);
>> + }
>> +
>> return -1;
>> }
>>
>> Index: gcc/c-family/c-common.c
>> ===================================================================
>> --- gcc/c-family/c-common.c (revision 269704)
>> +++ gcc/c-family/c-common.c (working copy)
>> @@ -3681,6 +3681,15 @@ c_common_get_alias_set (tree t)
>> return get_alias_set (t1);
>> }
>>
>> + /* Allow aliasing between enumeral types and the underlying
>> + integer type. This is required since those are compatible
>types. */
>> + else if (TREE_CODE (t) == ENUMERAL_TYPE)
>> + {
>> + tree t1 = c_common_type_for_size (tree_to_uhwi (TYPE_SIZE
>(t)),
>> + false /* short-cut above */);
>> + return get_alias_set (t1);
>> + }
>> +
>> return -1;
>> }
>> >
>> Index: gcc/testsuite/c-c++-common/torture/pr71598-1.c
>> ===================================================================
>> --- gcc/testsuite/c-c++-common/torture/pr71598-1.c (nonexistent)
>> +++ gcc/testsuite/c-c++-common/torture/pr71598-1.c (working copy)
>> @@ -0,0 +1,21 @@
>> +/* { dg-do run } */
>> +/* { dg-additional-options "-fno-short-enums" } */
>> +
>> +enum e1 { c1 };
>> +
>> +__attribute__((noinline,noclone))
>> +int f(enum e1 *p, unsigned *q)
>> +{
>> + *p = c1;
>> + *q = 2;
>> + return *p;
>> +}
>> +
>> +int main()
>> +{
>> + unsigned x;
>> +
>> + if (f((enum e1 *)&x, &x) != 2)
>> + __builtin_abort();
>> + return 0;
>> +}
>> Index: gcc/testsuite/c-c++-common/torture/pr71598-2.c
>> ===================================================================
>> --- gcc/testsuite/c-c++-common/torture/pr71598-2.c (nonexistent)
>> +++ gcc/testsuite/c-c++-common/torture/pr71598-2.c (working copy)
>> @@ -0,0 +1,47 @@
>> +/* { dg-do run } */
>> +/* { dg-additional-options "-fshort-enums" } */
>> +
>> +enum e1 { c1 = -__INT_MAX__ };
>> +
>> +__attribute__((noinline,noclone))
>> +int f(enum e1 *p, signed int *q)
>> +{
>> + *p = c1;
>> + *q = 2;
>> + return *p;
>> +}
>> +
>> +enum e2 { c2 = __SHRT_MAX__ + 1};
>> +
>> +__attribute__((noinline,noclone))
>> +int g(enum e2 *p, unsigned short *q)
>> +{
>> + *p = c2;
>> + *q = 2;
>> + return *p;
>> +}
>> +
>> +enum e3 { c3 = __SCHAR_MAX__ };
>> +
>> +__attribute__((noinline,noclone))
>> +int h(enum e3 *p, unsigned char *q)
>> +{
>> + *p = c3;
>> + *q = 2;
>> + return *p;
>> +}
>> +
>> +int main()
>> +{
>> + signed x;
>> + unsigned short y;
>> + unsigned char z;
>> +
>> + if (f((enum e1 *)&x, &x) != 2)
>> + __builtin_abort();
>> + if (g((enum e2 *)&y, &y) != 2)
>> + __builtin_abort();
>> + if (h((enum e3 *)&z, &z) != 2)
>> + __builtin_abort();
>> + return 0;
>> +}
>>