This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix attribute handling


Currently the way that mode attributes are handled along with pointers
is ... incorrect. This changes the behavior to allow the size change and
fixes the dwarf2 debugging info. (AFAICT stabs, dwarf1 and coff just
can't handle size differences - at least not that I could tell).

Testcase at the end :)

Thoughts?

-eric

-- 
Yuppies wear socks.


2002-09-24  Eric Christopher  <echristo@redhat.com>

        * tree.c (build_pointer_type_for_mode): New function.
        (build_pointer_type): Use.
        (build_reference_type_for_mode): New function.
        (build_reference_type): Ditto.
        * tree.h: Declarations for new functions.
        * c-common.c (handle_mode_attribute): Use new functions. Check
for
        type.
        * stor-layout.c (layout_type): Depend on machine mode for
        REFERENCE_TYPE and POINTER_TYPE.
        * dwarf2out.c (simple_type_size_in_bits): Move upward in file.
        (modified_type_die): Use instead of PTR_SIZE for POINTER_TYPE
        and REFERENCE_TYPE.
	* testsuite/gcc.c-torture/compile/20020926-1.c: New testcase.


Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.384
diff -u -p -w -r1.384 c-common.c
--- c-common.c	23 Sep 2002 11:32:36 -0000	1.384
+++ c-common.c	26 Sep 2002 23:30:53 -0000
@@ -5597,6 +5597,7 @@ handle_mode_attribute (node, name, args,
       int len = strlen (p);
       enum machine_mode mode = VOIDmode;
       tree typefm;
+      tree ptr_type;
 
       if (len > 4 && p[0] == '_' && p[1] == '_'
 	  && p[len - 1] == '_' && p[len - 2] == '_')
@@ -5638,6 +5639,19 @@ handle_mode_attribute (node, name, args,
 	      return NULL_TREE;
 	    }
 
+	  if (TREE_CODE (type) == POINTER_TYPE)
+	    {
+	      ptr_type = build_pointer_type_for_mode (TREE_TYPE (type),
+						      mode);
+	      *node = ptr_type;
+	    }
+	  else if (TREE_CODE (type) == REFERENCE_TYPE)
+	    {
+	      ptr_type = build_reference_type_for_mode (TREE_TYPE (type),
+							mode);
+	      *node = ptr_type;
+	    }
+	  else
 	  *node = typefm;
 	  /* No need to layout the type here.  The caller should do this.  */
 	}
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.387
diff -u -p -w -r1.387 dwarf2out.c
--- dwarf2out.c	22 Sep 2002 14:09:30 -0000	1.387
+++ dwarf2out.c	26 Sep 2002 23:30:54 -0000
@@ -7480,6 +7480,27 @@ is_base_type (type)
   return 0;
 }
 
+/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
+   node, return the size in bits for the type if it is a constant, or else
+   return the alignment for the type if the type's size is not constant, or
+   else return BITS_PER_WORD if the type actually turns out to be an
+   ERROR_MARK node.  */
+
+static inline unsigned HOST_WIDE_INT
+simple_type_size_in_bits (type)
+     tree type;
+{
+
+  if (TREE_CODE (type) == ERROR_MARK)
+    return BITS_PER_WORD;
+  else if (TYPE_SIZE (type) == NULL_TREE)
+    return 0;
+  else if (host_integerp (TYPE_SIZE (type), 1))
+    return tree_low_cst (TYPE_SIZE (type), 1);
+  else
+    return TYPE_ALIGN (type);
+}
+
 /* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging
    entry that chains various modifiers in front of the given type.  */
 
@@ -7557,7 +7578,8 @@ modified_type_die (type, is_const_type, 
       else if (code == POINTER_TYPE)
 	{
 	  mod_type_die = new_die (DW_TAG_pointer_type, comp_unit_die, type);
-	  add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
+	  add_AT_unsigned (mod_type_die, DW_AT_byte_size,
+			   simple_type_size_in_bits (type) / BITS_PER_UNIT);
 #if 0
 	  add_AT_unsigned (mod_type_die, DW_AT_address_class, 0);
 #endif
@@ -7566,7 +7588,8 @@ modified_type_die (type, is_const_type, 
       else if (code == REFERENCE_TYPE)
 	{
 	  mod_type_die = new_die (DW_TAG_reference_type, comp_unit_die, type);
-	  add_AT_unsigned (mod_type_die, DW_AT_byte_size, PTR_SIZE);
+	  add_AT_unsigned (mod_type_die, DW_AT_byte_size,
+			   simple_type_size_in_bits (type) / BITS_PER_UNIT);
 #if 0
 	  add_AT_unsigned (mod_type_die, DW_AT_address_class, 0);
 #endif
@@ -8419,27 +8442,6 @@ simple_decl_align_in_bits (decl)
      tree decl;
 {
   return (TREE_CODE (decl) != ERROR_MARK) ? DECL_ALIGN (decl) : BITS_PER_WORD;
-}
-
-/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
-   node, return the size in bits for the type if it is a constant, or else
-   return the alignment for the type if the type's size is not constant, or
-   else return BITS_PER_WORD if the type actually turns out to be an
-   ERROR_MARK node.  */
-
-static inline unsigned HOST_WIDE_INT
-simple_type_size_in_bits (type)
-     tree type;
-{
-
-  if (TREE_CODE (type) == ERROR_MARK)
-    return BITS_PER_WORD;
-  else if (TYPE_SIZE (type) == NULL_TREE)
-    return 0;
-  else if (host_integerp (TYPE_SIZE (type), 1))
-    return tree_low_cst (TYPE_SIZE (type), 1);
-  else
-    return TYPE_ALIGN (type);
 }
 
 /* Given a pointer to a FIELD_DECL, compute and return the byte offset of the
Index: stor-layout.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stor-layout.c,v
retrieving revision 1.129
diff -u -p -w -r1.129 stor-layout.c
--- stor-layout.c	18 Sep 2002 18:51:13 -0000	1.129
+++ stor-layout.c	26 Sep 2002 23:30:54 -0000
@@ -1611,15 +1611,15 @@ layout_type (type)
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       {
-	int nbits = ((TREE_CODE (type) == REFERENCE_TYPE
+
+	enum machine_mode mode = ((TREE_CODE (type) == REFERENCE_TYPE
 		      && reference_types_internal)
-		     ? GET_MODE_BITSIZE (Pmode) : POINTER_SIZE);
+				  ? Pmode : TYPE_MODE (type));
 
-	TYPE_MODE (type) = nbits == POINTER_SIZE ? ptr_mode : Pmode;
-	TYPE_SIZE (type) = bitsize_int (nbits);
-	TYPE_SIZE_UNIT (type) = size_int (nbits / BITS_PER_UNIT);
+	TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (mode));
+	TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (mode));
 	TREE_UNSIGNED (type) = 1;
-	TYPE_PRECISION (type) = nbits;
+	TYPE_PRECISION (type) = GET_MODE_BITSIZE (mode);
       }
       break;
 
Index: tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.c,v
retrieving revision 1.273
diff -u -p -w -r1.273 tree.c
--- tree.c	17 Sep 2002 13:03:40 -0000	1.273
+++ tree.c	26 Sep 2002 23:30:54 -0000
@@ -3495,26 +3495,24 @@ compare_tree_int (t, u)
    (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
    constructed by language-dependent code, not here.)  */
 
-/* Construct, lay out and return the type of pointers to TO_TYPE.
-   If such a type has already been constructed, reuse it.  */
-
 tree
-build_pointer_type (to_type)
+build_pointer_type_for_mode (to_type, mode)
      tree to_type;
+     enum machine_mode mode;
 {
   tree t = TYPE_POINTER_TO (to_type);
 
   /* First, if we already have a type for pointers to TO_TYPE, use it.  */
-
-  if (t != 0)
+  if (t != 0 && mode == ptr_mode)
     return t;
 
-  /* We need a new one.  */
   t = make_node (POINTER_TYPE);
 
   TREE_TYPE (t) = to_type;
+  TYPE_MODE (t) = mode;
 
   /* Record this type as the pointer to TO_TYPE.  */
+  if (mode == ptr_mode)
   TYPE_POINTER_TO (to_type) = t;
 
   /* Lay out the type.  This function has many callers that are concerned
@@ -3525,30 +3523,50 @@ build_pointer_type (to_type)
   return t;
 }
 
-/* Build the node for the type of references-to-TO_TYPE.  */
+/* Construct, lay out and return the type of pointers to TO_TYPE.
+   If such a type has already been constructed, reuse it.  */
 
 tree
-build_reference_type (to_type)
+build_pointer_type (to_type)
+     tree to_type;
+{
+  return build_pointer_type_for_mode (to_type, ptr_mode);
+}
+
+
+tree
+build_reference_type_for_mode (to_type, mode)
      tree to_type;
+     enum machine_mode mode;
 {
   tree t = TYPE_REFERENCE_TO (to_type);
 
   /* First, if we already have a type for pointers to TO_TYPE, use it.  */
-
-  if (t)
+  if (t != 0 && mode == ptr_mode)
     return t;
 
-  /* We need a new one.  */
   t = make_node (REFERENCE_TYPE);
 
   TREE_TYPE (t) = to_type;
+  TYPE_MODE (t) = mode;
 
   /* Record this type as the pointer to TO_TYPE.  */
+  if (mode == ptr_mode)
   TYPE_REFERENCE_TO (to_type) = t;
 
   layout_type (t);
 
   return t;
+}
+
+
+/* Build the node for the type of references-to-TO_TYPE.  */
+
+tree
+build_reference_type (to_type)
+     tree to_type;
+{
+  return build_reference_type_for_mode (to_type, ptr_mode);
 }
 
 /* Build a type that is compatible with t but has no cv quals anywhere
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.353
diff -u -p -w -r1.353 tree.h
--- tree.h	20 Sep 2002 07:33:25 -0000	1.353
+++ tree.h	26 Sep 2002 23:30:54 -0000
@@ -2177,7 +2177,9 @@ extern tree make_unsigned_type		PARAMS (
 extern void initialize_sizetypes	PARAMS ((void));
 extern void set_sizetype		PARAMS ((tree));
 extern void fixup_unsigned_type		PARAMS ((tree));
+extern tree build_pointer_type_for_mode PARAMS ((tree, enum machine_mode));
 extern tree build_pointer_type		PARAMS ((tree));
+extern tree build_reference_type_for_mode PARAMS ((tree, enum machine_mode));
 extern tree build_reference_type 	PARAMS ((tree));
 extern tree build_type_no_quals 	PARAMS ((tree));
 extern tree build_index_type		PARAMS ((tree));


int * __attribute__ ((mode (SI))) ip1;

int *ip2;

struct {
  int * __attribute__ ((mode (SI))) ip;
} is1;

struct {
  int *ip;
} is2;

int ints[] = {1, 2, 3, 4};

int main (int argc, char **argv)
{
  ip1 = ints;
  ip1[2] = 42;
  ip2 = ints;
  ip2[2] = 42;
  is1.ip = ints;
  is2.ip = ints;
  return 0;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]