[PATCH] Fix PR71598, aliasing between enums and compatible types

Michael Matz matz@suse.de
Fri Mar 15 15:13:00 GMT 2019


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.


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



More information about the Gcc-patches mailing list