[PATCH] Fix PR71598, aliasing between enums and compatible types
Iain Sandoe
idsandoe@googlemail.com
Mon Mar 18 09:58:00 GMT 2019
> On 18 Mar 2019, at 09:12, Richard Biener <rguenther@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 <rguenther@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;
> +}
More information about the Gcc-patches
mailing list