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 to finish_layout/check_field_decls for c++/13983 and c++/17519


Both of these PRs are about check_field_decls failing to recognize that the field type is in fact a packed non-POD type, and then complaining that it's a uppacked non-POD type. Fixed by stripping array types before checking TYPE_PACKED (17519) and properly copying TYPE_PACKED to variants of class template instantiations (13983).

Tested x86_64-pc-linux-gnu, applied to trunk.
2006-07-05  Jason Merrill  <jason@redhat.com>

	PR c++/13983
	PR c++/17519
	* stor-layout.c (finish_record_layout): Copy TYPE_PACKED to variants.
	* c-common.c (handle_packed_attribute): So don't copy it here.
	* c-decl.c (finish_struct): Don't copy TYPE_ALIGN.
	* cp/class.c (check_field_decls): Check TYPE_PACKED after
	stripping array types.
	(finish_struct_bits): Don't copy TYPE_SIZE here.

Index: stor-layout.c
===================================================================
*** stor-layout.c	(revision 115216)
--- stor-layout.c	(working copy)
*************** finalize_type_size (tree type)
*** 1465,1470 ****
--- 1465,1472 ----
  void
  finish_record_layout (record_layout_info rli, int free_p)
  {
+   tree variant;
+ 
    /* Compute the final size.  */
    finalize_record_size (rli);
  
*************** finish_record_layout (record_layout_info
*** 1474,1479 ****
--- 1476,1487 ----
    /* Perform any last tweaks to the TYPE_SIZE, etc.  */
    finalize_type_size (rli->t);
  
+   /* Propagate TYPE_PACKED to variants.  With C++ templates,
+      handle_packed_attribute is too early to do this.  */
+   for (variant = TYPE_NEXT_VARIANT (rli->t); variant;
+        variant = TYPE_NEXT_VARIANT (variant))
+     TYPE_PACKED (variant) = TYPE_PACKED (rli->t);
+ 
    /* Lay out any static members.  This is done now because their type
       may use the record's type.  */
    while (rli->pending_statics)
Index: c-common.c
===================================================================
*** c-common.c	(revision 115216)
--- c-common.c	(working copy)
*************** handle_packed_attribute (tree *node, tre
*** 4082,4101 ****
        if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE))
  	*node = build_variant_type_copy (*node);
        TYPE_PACKED (*node) = 1;
-       if (TYPE_MAIN_VARIANT (*node) == *node)
- 	{
- 	  /* If it is the main variant, then pack the other variants
- 	     too. This happens in,
- 
- 	     struct Foo {
- 	       struct Foo const *ptr; // creates a variant w/o packed flag
- 	     } __ attribute__((packed)); // packs it now.
- 	   */
- 	  tree probe;
- 
- 	  for (probe = *node; probe; probe = TYPE_NEXT_VARIANT (probe))
- 	    TYPE_PACKED (probe) = 1;
- 	}
      }
    else if (TREE_CODE (*node) == FIELD_DECL)
      {
--- 4082,4087 ----
Index: c-decl.c
===================================================================
*** c-decl.c	(revision 115216)
--- c-decl.c	(working copy)
*************** finish_struct (tree t, tree fieldlist, t
*** 5574,5581 ****
      {
        TYPE_FIELDS (x) = TYPE_FIELDS (t);
        TYPE_LANG_SPECIFIC (x) = TYPE_LANG_SPECIFIC (t);
-       TYPE_ALIGN (x) = TYPE_ALIGN (t);
-       TYPE_USER_ALIGN (x) = TYPE_USER_ALIGN (t);
        C_TYPE_FIELDS_READONLY (x) = C_TYPE_FIELDS_READONLY (t);
        C_TYPE_FIELDS_VOLATILE (x) = C_TYPE_FIELDS_VOLATILE (t);
        C_TYPE_VARIABLE_SIZE (x) = C_TYPE_VARIABLE_SIZE (t);
--- 5574,5579 ----
Index: cp/class.c
===================================================================
*** cp/class.c	(revision 115216)
--- cp/class.c	(working copy)
*************** finish_struct_bits (tree t)
*** 1433,1440 ****
        TYPE_VFIELD (variants) = TYPE_VFIELD (t);
        TYPE_METHODS (variants) = TYPE_METHODS (t);
        TYPE_FIELDS (variants) = TYPE_FIELDS (t);
-       TYPE_SIZE (variants) = TYPE_SIZE (t);
-       TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t);
      }
  
    if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
--- 1433,1438 ----
*************** check_field_decls (tree t, tree *access_
*** 2815,2854 ****
  
        next = &TREE_CHAIN (x);
  
-       if (TREE_CODE (x) == FIELD_DECL)
- 	{
- 	  if (TYPE_PACKED (t))
- 	    {
- 	      if (!pod_type_p (TREE_TYPE (x)) && !TYPE_PACKED (TREE_TYPE (x)))
- 		warning
- 		  (0,
- 		   "ignoring packed attribute on unpacked non-POD field %q+#D",
- 		   x);
- 	      else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
- 		DECL_PACKED (x) = 1;
- 	    }
- 
- 	  if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
- 	    /* We don't treat zero-width bitfields as making a class
- 	       non-empty.  */
- 	    ;
- 	  else
- 	    {
- 	      tree element_type;
- 
- 	      /* The class is non-empty.  */
- 	      CLASSTYPE_EMPTY_P (t) = 0;
- 	      /* The class is not even nearly empty.  */
- 	      CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
- 	      /* If one of the data members contains an empty class,
- 		 so does T.  */
- 	      element_type = strip_array_types (type);
- 	      if (CLASS_TYPE_P (element_type)
- 		  && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))
- 		CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
- 	    }
- 	}
- 
        if (TREE_CODE (x) == USING_DECL)
  	{
  	  /* Prune the access declaration from the list of fields.  */
--- 2813,2818 ----
*************** check_field_decls (tree t, tree *access_
*** 2945,2950 ****
--- 2909,2942 ----
  
        type = strip_array_types (type);
  
+       if (TYPE_PACKED (t))
+ 	{
+ 	  if (!pod_type_p (type) && !TYPE_PACKED (type))
+ 	    warning
+ 	      (0,
+ 	       "ignoring packed attribute on unpacked non-POD field %q+#D",
+ 	       x);
+ 	  else if (TYPE_ALIGN (TREE_TYPE (x)) > BITS_PER_UNIT)
+ 	    DECL_PACKED (x) = 1;
+ 	}
+ 
+       if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))
+ 	/* We don't treat zero-width bitfields as making a class
+ 	   non-empty.  */
+ 	;
+       else
+ 	{
+ 	  /* The class is non-empty.  */
+ 	  CLASSTYPE_EMPTY_P (t) = 0;
+ 	  /* The class is not even nearly empty.  */
+ 	  CLASSTYPE_NEARLY_EMPTY_P (t) = 0;
+ 	  /* If one of the data members contains an empty class,
+ 	     so does T.  */
+ 	  if (CLASS_TYPE_P (type)
+ 	      && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (type))
+ 	    CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;
+ 	}
+ 
        /* This is used by -Weffc++ (see below). Warn only for pointers
  	 to members which might hold dynamic memory. So do not warn
  	 for pointers to functions or pointers to members.  */
Index: testsuite/g++.dg/ext/packed10.C
===================================================================
*** testsuite/g++.dg/ext/packed10.C	(revision 0)
--- testsuite/g++.dg/ext/packed10.C	(revision 0)
***************
*** 0 ****
--- 1,14 ----
+ // PR c++/13983, c++/17519
+ // The typedef and the array were causing us to miss that A<int> is
+ // a packed type.
+ 
+ template <class T>
+ struct A {
+   A();
+ } __attribute__((packed));
+ 
+ typedef A<int> Ai;
+ 
+ struct B {
+   Ai a[2];
+ } __attribute__((packed));

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