> On 18 Mar 2019, at 09:12, Richard Biener <rguent...@suse.de> wrote: > > On Fri, 15 Mar 2019, Jason Merrill wrote: > >> On 3/15/19 9:33 AM, 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. >> >> This does not apply to C++; an enum does not alias its underlying type. > > Thus the following different patch, introducing c_get_alias_set and > only doing the special handling for C family frontends (I assume > that at least ObjC is also affected).
As far as ObjC is concerned, I’m not aware of any special rule, thus it should behave as per the underlying C impl (therefore if it’s OK for C it is OK for ObjC). Iain > Bootstrap & regtest running on x86_64-unknown-linux-gnu, OK? > > Thanks, > Richard. > > 2019-03-18 Richard Biener <rguent...@suse.de> > > PR c/71598 > * gimple.c: Include langhooks.h. > (gimple_get_alias_set): Treat enumeral types as the underlying > integer type. > > c/ > * c-tree.h (c_get_alias_set): Declare. > * c-objc-common.h (LANG_HOOKS_GET_ALIAS_SET): Use c_get_alias_set. > * c-objc-common.c (c_get_alias_set): Treat enumeral types > as the underlying integer type. > > * gcc.dg/torture/pr71598-1.c: New testcase. > * gcc.dg/torture/pr71598-2.c: Likewise. > > > Index: gcc/c/c-objc-common.c > =================================================================== > --- gcc/c/c-objc-common.c (revision 269752) > +++ gcc/c/c-objc-common.c (working copy) > @@ -265,3 +265,22 @@ c_vla_unspec_p (tree x, tree fn ATTRIBUT > { > return c_vla_type_p (x); > } > + > +/* Special routine to get the alias set of T for C. */ > + > +alias_set_type > +c_get_alias_set (tree t) > +{ > + /* Allow aliasing between enumeral types and the underlying > + integer type. This is required since those are compatible types. */ > + if (TREE_CODE (t) == ENUMERAL_TYPE) > + { > + tree t1 = c_common_type_for_size (tree_to_uhwi (TYPE_SIZE (t)), > + /* short-cut commoning to signed > + type. */ > + false); > + return get_alias_set (t1); > + } > + > + return c_common_get_alias_set (t); > +} > Index: gcc/c/c-objc-common.h > =================================================================== > --- gcc/c/c-objc-common.h (revision 269752) > +++ gcc/c/c-objc-common.h (working copy) > @@ -43,7 +43,7 @@ along with GCC; see the file COPYING3. > #undef LANG_HOOKS_POST_OPTIONS > #define LANG_HOOKS_POST_OPTIONS c_common_post_options > #undef LANG_HOOKS_GET_ALIAS_SET > -#define LANG_HOOKS_GET_ALIAS_SET c_common_get_alias_set > +#define LANG_HOOKS_GET_ALIAS_SET c_get_alias_set > #undef LANG_HOOKS_PARSE_FILE > #define LANG_HOOKS_PARSE_FILE c_common_parse_file > #undef LANG_HOOKS_FINISH_INCOMPLETE_DECL > Index: gcc/c/c-tree.h > =================================================================== > --- gcc/c/c-tree.h (revision 269752) > +++ gcc/c/c-tree.h (working copy) > @@ -623,6 +623,7 @@ extern bool c_missing_noreturn_ok_p (tre > extern bool c_warn_unused_global_decl (const_tree); > extern void c_initialize_diagnostics (diagnostic_context *); > extern bool c_vla_unspec_p (tree x, tree fn); > +extern alias_set_type c_get_alias_set (tree); > > /* in c-typeck.c */ > extern int in_alignof; > Index: gcc/gimple.c > =================================================================== > --- gcc/gimple.c (revision 269752) > +++ 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/testsuite/gcc.dg/torture/pr71598-1.c > =================================================================== > --- gcc/testsuite/gcc.dg/torture/pr71598-1.c (nonexistent) > +++ gcc/testsuite/gcc.dg/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(&x, &x) != 2) > + __builtin_abort(); > + return 0; > +} > Index: gcc/testsuite/gcc.dg/torture/pr71598-2.c > =================================================================== > --- gcc/testsuite/gcc.dg/torture/pr71598-2.c (nonexistent) > +++ gcc/testsuite/gcc.dg/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(&x, &x) != 2) > + __builtin_abort(); > + if (g(&y, &y) != 2) > + __builtin_abort(); > + if (h(&z, &z) != 2) > + __builtin_abort(); > + return 0; > +}