> 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;
> +}

Reply via email to