re PR c/71598 (Wrong optimization with aliasing enums)
authorRichard Biener <rguenther@suse.de>
Mon, 1 Apr 2019 07:16:38 +0000 (07:16 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 1 Apr 2019 07:16:38 +0000 (07:16 +0000)
2019-04-01  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.
* gcc.dg/torture/pr71598-3.c: Likewise.

From-SVN: r270052

gcc/ChangeLog
gcc/c/ChangeLog
gcc/c/c-objc-common.c
gcc/c/c-objc-common.h
gcc/c/c-tree.h
gcc/gimple.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr71598-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr71598-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/torture/pr71598-3.c [new file with mode: 0644]

index 136785149168c938688567b639ddd7b397777ad1..6982daaab18aab1817e24078a3e2ce75d843c735 100644 (file)
@@ -1,3 +1,10 @@
+2019-04-01  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.
+
 2019-03-29  Kugan Vivekanandarajah  <kuganv@linaro.org>
            Eric Botcazou  <ebotcazou@adacore.com>
 
index fc8049e832e74fc49e0a5f7d9e96de577ed0cac5..076a9a26501c0c87645c29092473a9a881c52975 100644 (file)
@@ -1,3 +1,11 @@
+2019-04-01  Richard Biener  <rguenther@suse.de>
+
+       PR c/71598
+       * 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.
+
 2019-03-19  Martin Sebor  <msebor@redhat.com>
 
        PR tree-optimization/89688
index 21ca7e6f84fd2eb1a06179a2fac0297d86196fb9..2b76737a74a58b0df49086ae1fcebeb517652857 100644 (file)
@@ -265,3 +265,22 @@ c_vla_unspec_p (tree x, tree fn ATTRIBUTE_UNUSED)
 {
   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 7a90c7705ea1640df70b817c08ffc81a210e07b7..f5e820420f6b0c6322230c727ba612d95b826f5d 100644 (file)
@@ -43,7 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #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 d6e345afb37b940e268b870ba7728968600f66ea..9393f6d15454a44dd5183ca20f4d805e61008af8 100644 (file)
@@ -623,6 +623,7 @@ extern bool c_missing_noreturn_ok_p (tree);
 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 3a91d1cb35031ee45330897f9f788c023390e365..8fae60fb848b60317e46532f8672f9fa7d4b2ad8 100644 (file)
@@ -44,6 +44,7 @@ along with GCC; see the file COPYING3.  If not see
 #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 deb903bdc69eb202a64d8584607bc36f6f4a6d7d..a6ac581f74484ee695c53062aeae392a50316b89 100644 (file)
@@ -1,3 +1,10 @@
+2019-04-01  Richard Biener  <rguenther@suse.de>
+
+       PR c/71598
+       * gcc.dg/torture/pr71598-1.c: New testcase.
+       * gcc.dg/torture/pr71598-2.c: Likewise.
+       * gcc.dg/torture/pr71598-3.c: Likewise.
+
 2019-03-31  Marek Polacek  <polacek@redhat.com>
 
        PR c++/89852 - ICE with C++11 functional cast with { }.
diff --git a/gcc/testsuite/gcc.dg/torture/pr71598-1.c b/gcc/testsuite/gcc.dg/torture/pr71598-1.c
new file mode 100644 (file)
index 0000000..7dfcb3d
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr71598-2.c b/gcc/testsuite/gcc.dg/torture/pr71598-2.c
new file mode 100644 (file)
index 0000000..f140287
--- /dev/null
@@ -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;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr71598-3.c b/gcc/testsuite/gcc.dg/torture/pr71598-3.c
new file mode 100644 (file)
index 0000000..0b4b842
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+
+enum e1 { A, B };
+enum e2 { C, D };
+
+__attribute__((noinline,noclone))
+enum e1 f(unsigned int *p)
+{
+  *(enum e1 *)p = A;
+  *(enum e2 *)p = D;
+  return *(enum e1 *)p;
+}
+
+int main()
+{
+  unsigned int storage;
+
+  if (f(&storage) != B)
+    __builtin_abort();
+  return 0;
+}