From 99db1ef0e250b9b61fd557feb33e954a0b4679e6 Mon Sep 17 00:00:00 2001
From: Richard Henderson <rth@redhat.com>
Date: Sat, 24 Sep 2005 09:21:43 -0700
Subject: [PATCH] c-common.c (handle_mode_attribute): When not modifying in
 place, create subtypes for enumerations.

        * c-common.c (handle_mode_attribute): When not modifying in place,
        create subtypes for enumerations.
        (sync_resolve_return): Use TYPE_MAIN_VARIANT.
        * gimplify.c (create_tmp_from_val): Likewise.

From-SVN: r104603
---
 gcc/ChangeLog  |  7 +++++++
 gcc/c-common.c | 34 +++++++++++++++++++---------------
 gcc/gimplify.c |  2 +-
 3 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7d63a5bd6c1f..25938ff74b2c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2005-09-24  Richard Henderson  <rth@redhat.com>
+
+	* c-common.c (handle_mode_attribute): When not modifying in place,
+	create subtypes for enumerations.
+	(sync_resolve_return): Use TYPE_MAIN_VARIANT.
+	* gimplify.c (create_tmp_from_val): Likewise.
+
 2005-09-24  Alexandre Oliva  <aoliva@redhat.com>
 
 	* config/i386/i386.md (*tls_global_dynamic_64,
diff --git a/gcc/c-common.c b/gcc/c-common.c
index edd744893cba..fe4bd8c48647 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -4520,21 +4520,24 @@ handle_mode_attribute (tree *node, tree name, tree args,
 	      return NULL_TREE;
 	    }
 
-	  if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
-	    type = build_variant_type_copy (type);
-
-	  /* We cannot use layout_type here, because that will attempt
-	     to re-layout all variants, corrupting our original.  */
-	  TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
-	  TYPE_MIN_VALUE (type) = TYPE_MIN_VALUE (typefm);
-	  TYPE_MAX_VALUE (type) = TYPE_MAX_VALUE (typefm);
-	  TYPE_SIZE (type) = TYPE_SIZE (typefm);
-	  TYPE_SIZE_UNIT (type) = TYPE_SIZE_UNIT (typefm);
-	  TYPE_MODE (type) = TYPE_MODE (typefm);
-	  if (!TYPE_USER_ALIGN (type))
-	    TYPE_ALIGN (type) = TYPE_ALIGN (typefm);
-
-	  typefm = type;
+	  if (flags & ATTR_FLAG_TYPE_IN_PLACE)
+	    {
+	      TYPE_PRECISION (type) = TYPE_PRECISION (typefm);
+	      typefm = type;
+	    }
+	  else
+	    {
+	      /* We cannot build a type variant, as there's code that assumes
+		 that TYPE_MAIN_VARIANT has the same mode.  This includes the
+		 debug generators.  Instead, create a subrange type.  This
+		 results in all of the enumeral values being emitted only once
+		 in the original, and the subtype gets them by reference.  */
+	      if (TYPE_UNSIGNED (type))
+		typefm = make_unsigned_type (TYPE_PRECISION (typefm));
+	      else
+		typefm = make_signed_type (TYPE_PRECISION (typefm));
+	      TREE_TYPE (typefm) = type;
+	    }
 	}
       else if (VECTOR_MODE_P (mode)
 	       ? TREE_CODE (type) != TREE_CODE (TREE_TYPE (typefm))
@@ -6119,6 +6122,7 @@ static tree
 sync_resolve_return (tree params, tree result)
 {
   tree ptype = TREE_TYPE (TREE_TYPE (TREE_VALUE (params)));
+  ptype = TYPE_MAIN_VARIANT (ptype);
   return convert (ptype, result);
 }
 
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index cba1704e8a0a..42b8740d0833 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -404,7 +404,7 @@ get_name (tree t)
 static inline tree
 create_tmp_from_val (tree val)
 {
-  return create_tmp_var (TREE_TYPE (val), get_name (val));
+  return create_tmp_var (TYPE_MAIN_VARIANT (TREE_TYPE (val)), get_name (val));
 }
 
 /* Create a temporary to hold the value of VAL.  If IS_FORMAL, try to reuse
-- 
GitLab