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]

Re: C++ PATCH: Check pod-class


Jason Merrill wrote:
> a static member is OK.  It would certainly be odd to use offsetof for that
> purpose, but a NULL pointer does not necessarily indicate they're using
> offsetof, and we should be very selective about unconditional warnings.
Ok, yes it certainly is odd. With your and Mark Mitchell's comments, I've
decided to remove the offsetof stuff from this patch -- it gets too many false
positives and the like. Although it's undefined, it'll work for member
variables provided there are no virtual bases. For those cases we die anyway.

I've split the patch into two. One for pod and one to tidy up typeck.c. (Do you
prefer them separated in functionality, or combined?)

So, the first patch just adds the non_pod flag, updates pod_type_p. call.c and
finish_struct_1. This makes pod_type_p do what it's supposed to do. Some of the
testsuite still needs patching, because it is passing non-POD through ... . I
trust that warning is unconditionally ok, it was there before, just not working
:-)

The other patch cleans up build_component_addr, which no longer needs a
separate MSG argument. It also replaces some error calls with cp_error calls,
thus removing IDENTIFIER_POINTER uses.

Enjoy

nathan


-- 
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
      You can up the bandwidth, but you can't up the speed of light      
nathan@acm.org  http://www.cs.bris.ac.uk/~nathan/  nathan@cs.bris.ac.uk
egcs/gcc/cp/ChangeLog:
Mon Apr 12 10:24:13 BST 1999  Nathan Sidwell  <nathan@acm.org>

	* call.c (convert_arg_to_ellipsis): Use pod_type_p.
	* cp-tree.h (struct lang_type): Added non_pod_class flag.
	(CLASSTYPE_NON_POD_P): New macro to access it.
	* class.c (finish_struct_1): Determine non-PODness.
	Check for arrays of pointers (-Weffc++).
	Remove array inspection duplicated code.
	* tree.c (pod_type_p): Use CLASSTYPE_NON_POD_P.
	
Index: egcs/gcc/cp/call.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/call.c,v
retrieving revision 1.140
diff -c -3 -p -r1.140 call.c
*** call.c	1999/04/02 15:36:02	1.140
--- call.c	1999/04/12 11:09:31
*************** convert_like (convs, expr)
*** 3142,3162 ****
  }
  
  /* ARG is being passed to a varargs function.  Perform any conversions
!    required.  Return the converted value.  */
  
  tree
  convert_arg_to_ellipsis (arg)
       tree arg;
  {
    if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
        && (TYPE_PRECISION (TREE_TYPE (arg))
  	  < TYPE_PRECISION (double_type_node)))
      /* Convert `float' to `double'.  */
      arg = cp_convert (double_type_node, arg);
-   else if (IS_AGGR_TYPE (TREE_TYPE (arg))
- 	   && ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (arg)))
-     cp_warning ("cannot pass objects of type `%T' through `...'",
- 		TREE_TYPE (arg));
    else
      /* Convert `short' and `char' to full-size `int'.  */
      arg = default_conversion (arg);
--- 3142,3166 ----
  }
  
  /* ARG is being passed to a varargs function.  Perform any conversions
!    required.  Array/function to pointer decay must have already happened.
!    Return the converted value.  */
  
  tree
  convert_arg_to_ellipsis (arg)
       tree arg;
  {
+   if (! pod_type_p (TREE_TYPE (arg)))
+     {
+       /* Undefined behaviour [expr.call] 5.2.2/7.  */
+       cp_warning ("cannot pass objects of non-POD type `%#T' through `...'",
+ 		  TREE_TYPE (arg));
+     }
+ 
    if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE
        && (TYPE_PRECISION (TREE_TYPE (arg))
  	  < TYPE_PRECISION (double_type_node)))
      /* Convert `float' to `double'.  */
      arg = cp_convert (double_type_node, arg);
    else
      /* Convert `short' and `char' to full-size `int'.  */
      arg = default_conversion (arg);
Index: egcs/gcc/cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.213
diff -c -3 -p -r1.213 cp-tree.h
*** cp-tree.h	1999/04/02 15:36:01	1.213
--- cp-tree.h	1999/04/12 11:09:33
*************** struct lang_type
*** 727,737 ****
        unsigned non_aggregate : 1;
        unsigned is_partial_instantiation : 1;
        unsigned has_mutable : 1;
  
        /* The MIPS compiler gets it wrong if this struct also
  	 does not fill out to a multiple of 4 bytes.  Add a
  	 member `dummy' with new bits if you go over the edge.  */
!       unsigned dummy : 11;
      } type_flags;
  
    int vsize;
--- 727,738 ----
        unsigned non_aggregate : 1;
        unsigned is_partial_instantiation : 1;
        unsigned has_mutable : 1;
+       unsigned non_pod_class : 1;
  
        /* The MIPS compiler gets it wrong if this struct also
  	 does not fill out to a multiple of 4 bytes.  Add a
  	 member `dummy' with new bits if you go over the edge.  */
!       unsigned dummy : 10;
      } type_flags;
  
    int vsize;
*************** struct lang_type
*** 1000,1005 ****
--- 1001,1009 ----
  /* Nonzero means that this type contains a mutable member */
  #define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_mutable)
  #define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
+ 
+ /* Nonzero means that this class type is a non-POD class.  */
+ #define CLASSTYPE_NON_POD_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->type_flags.non_pod_class)
  
  /* A list of class types of which this type is a friend.  The
     TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the
Index: egcs/gcc/cp/class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.141
diff -c -3 -p -r1.141 class.c
*** class.c	1999/04/03 01:23:24	1.141
--- class.c	1999/04/12 11:09:37
*************** finish_struct_1 (t, warn_anon)
*** 3097,3102 ****
--- 3097,3103 ----
    int cant_have_const_ctor;
    int no_const_asn_ref;
    int has_mutable = 0;
+   int non_pod_class = 0;
  
    /* The index of the first base class which has virtual
       functions.  Only applied to non-virtual baseclasses.  */
*************** finish_struct_1 (t, warn_anon)
*** 3243,3248 ****
--- 3244,3250 ----
    last_x = NULL_TREE;
    for (x = fields; x; x = TREE_CHAIN (x))
      {
+       tree type = TREE_TYPE (x);
        GNU_xref_member (current_class_name, x);
  
        if (TREE_CODE (x) == FIELD_DECL)
*************** finish_struct_1 (t, warn_anon)
*** 3284,3304 ****
  
        /* Perform error checking that did not get done in
  	 grokdeclarator.  */
!       if (TREE_CODE (TREE_TYPE (x)) == FUNCTION_TYPE)
  	{
  	  cp_error_at ("field `%D' invalidly declared function type",
  		       x);
! 	  TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
  	}
!       else if (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE)
  	{
  	  cp_error_at ("field `%D' invalidly declared method type", x);
! 	  TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
  	}
!       else if (TREE_CODE (TREE_TYPE (x)) == OFFSET_TYPE)
  	{
  	  cp_error_at ("field `%D' invalidly declared offset type", x);
! 	  TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
  	}
  
  #if 0
--- 3286,3309 ----
  
        /* Perform error checking that did not get done in
  	 grokdeclarator.  */
!       if (TREE_CODE (type) == FUNCTION_TYPE)
  	{
  	  cp_error_at ("field `%D' invalidly declared function type",
  		       x);
! 	  type = build_pointer_type (type);
! 	  TREE_TYPE (x) = type;
  	}
!       else if (TREE_CODE (type) == METHOD_TYPE)
  	{
  	  cp_error_at ("field `%D' invalidly declared method type", x);
! 	  type = build_pointer_type (type);
! 	  TREE_TYPE (x) = type;
  	}
!       else if (TREE_CODE (type) == OFFSET_TYPE)
  	{
  	  cp_error_at ("field `%D' invalidly declared offset type", x);
! 	  type = build_pointer_type (type);
! 	  TREE_TYPE (x) = type;
  	}
  
  #if 0
*************** finish_struct_1 (t, warn_anon)
*** 3336,3341 ****
--- 3341,3348 ----
  	 Also do a little ANSI jig if necessary.  */
        if (TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE)
   	{
+           non_pod_class = 1;
+           
  	  if (DECL_INITIAL (x) == NULL_TREE)
  	    ref_sans_init = 1;
  
*************** finish_struct_1 (t, warn_anon)
*** 3355,3366 ****
  	    }
  	}
  
!       if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
  	has_pointers = 1;
  
!       if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (TREE_TYPE (x)))
          has_mutable = 1;
  
        /* If any field is const, the structure type is pseudo-const.  */
        if (TREE_READONLY (x))
  	{
--- 3362,3380 ----
  	    }
  	}
  
!       while (TREE_CODE (type) == ARRAY_TYPE)
!         type = TREE_TYPE (type);
!       
!       if (TREE_CODE (type) == POINTER_TYPE)
  	has_pointers = 1;
  
!       if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
          has_mutable = 1;
  
+       if (! pod_type_p (type) || TYPE_PTRMEM_P (type)
+           || TYPE_PTRMEMFUNC_P (type))
+         non_pod_class = 1;
+ 
        /* If any field is const, the structure type is pseudo-const.  */
        if (TREE_READONLY (x))
  	{
*************** finish_struct_1 (t, warn_anon)
*** 3388,3401 ****
  	{
  	  /* A field that is pseudo-const makes the structure
  	     likewise.  */
! 	  tree t1 = TREE_TYPE (x);
! 	  while (TREE_CODE (t1) == ARRAY_TYPE)
! 	    t1 = TREE_TYPE (t1);
! 	  if (IS_AGGR_TYPE (t1))
  	    {
! 	      if (C_TYPE_FIELDS_READONLY (t1))
  		C_TYPE_FIELDS_READONLY (t) = 1;
! 	      if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (t1))
  		const_sans_init = 1;
  	    }
  	}
--- 3402,3412 ----
  	{
  	  /* A field that is pseudo-const makes the structure
  	     likewise.  */
! 	  if (IS_AGGR_TYPE (type))
  	    {
! 	      if (C_TYPE_FIELDS_READONLY (type))
  		C_TYPE_FIELDS_READONLY (t) = 1;
! 	      if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
  		const_sans_init = 1;
  	    }
  	}
*************** finish_struct_1 (t, warn_anon)
*** 3407,3413 ****
  	  /* Invalid bit-field size done by grokfield.  */
  	  /* Detect invalid bit-field type.  */
  	  if (DECL_INITIAL (x)
! 	      && ! INTEGRAL_TYPE_P (TREE_TYPE (x)))
  	    {
  	      cp_error_at ("bit-field `%#D' with non-integral type", x);
  	      DECL_INITIAL (x) = NULL;
--- 3418,3424 ----
  	  /* Invalid bit-field size done by grokfield.  */
  	  /* Detect invalid bit-field type.  */
  	  if (DECL_INITIAL (x)
! 	      && ! (type == TREE_TYPE (x) && INTEGRAL_TYPE_P (type)))
  	    {
  	      cp_error_at ("bit-field `%#D' with non-integral type", x);
  	      DECL_INITIAL (x) = NULL;
*************** finish_struct_1 (t, warn_anon)
*** 3455,3474 ****
  			 TYPE_PRECISION (long_long_unsigned_type_node));
  		  cp_error_at ("  in declaration of `%D'", x);
  		}
! 	      else if (width > TYPE_PRECISION (TREE_TYPE (x))
! 		       && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE
! 		       && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE)
  		{
  		  cp_warning_at ("width of `%D' exceeds its type", x);
  		}
! 	      else if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE
! 		       && ((min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)),
! 					   TREE_UNSIGNED (TREE_TYPE (x))) > width)
! 			   || (min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)),
! 					      TREE_UNSIGNED (TREE_TYPE (x))) > width)))
  		{
  		  cp_warning_at ("`%D' is too small to hold all values of `%#T'",
! 				 x, TREE_TYPE (x));
  		}
  
  	      if (DECL_INITIAL (x))
--- 3466,3485 ----
  			 TYPE_PRECISION (long_long_unsigned_type_node));
  		  cp_error_at ("  in declaration of `%D'", x);
  		}
! 	      else if (width > TYPE_PRECISION (type)
! 		       && TREE_CODE (type) != ENUMERAL_TYPE
! 		       && TREE_CODE (type) != BOOLEAN_TYPE)
  		{
  		  cp_warning_at ("width of `%D' exceeds its type", x);
  		}
! 	      else if (TREE_CODE (type) == ENUMERAL_TYPE
! 		       && ((min_precision (TYPE_MIN_VALUE (type),
! 					   TREE_UNSIGNED (type)) > width)
! 			   || (min_precision (TYPE_MAX_VALUE (type),
! 					      TREE_UNSIGNED (type)) > width)))
  		{
  		  cp_warning_at ("`%D' is too small to hold all values of `%#T'",
! 				 x, type);
  		}
  
  	      if (DECL_INITIAL (x))
*************** finish_struct_1 (t, warn_anon)
*** 3486,3507 ****
  #ifdef PCC_BITFIELD_TYPE_MATTERS
  		      if (PCC_BITFIELD_TYPE_MATTERS)
  			DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
! 					      TYPE_ALIGN (TREE_TYPE (x)));
  #endif
  		    }
  		}
  	    }
  	  else
  	    /* Non-bit-fields are aligned for their type.  */
! 	    DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (TREE_TYPE (x)));
  	}
        else
  	{
- 	  tree type = TREE_TYPE (x);
- 
- 	  while (TREE_CODE (type) == ARRAY_TYPE)
- 	    type = TREE_TYPE (type);
- 
  	  if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x)
  	      && ! TYPE_PTRMEMFUNC_P (type))
  	    {
--- 3497,3513 ----
  #ifdef PCC_BITFIELD_TYPE_MATTERS
  		      if (PCC_BITFIELD_TYPE_MATTERS)
  			DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
! 					      TYPE_ALIGN (type));
  #endif
  		    }
  		}
  	    }
  	  else
  	    /* Non-bit-fields are aligned for their type.  */
! 	    DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (type));
  	}
        else
  	{
  	  if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x)
  	      && ! TYPE_PTRMEMFUNC_P (type))
  	    {
*************** finish_struct_1 (t, warn_anon)
*** 3606,3611 ****
--- 3612,3620 ----
    if (! IS_SIGNATURE (t))
      CLASSTYPE_NON_AGGREGATE (t)
        = ! aggregate || has_virtual || TYPE_HAS_CONSTRUCTOR (t);
+   CLASSTYPE_NON_POD_P (t)
+       = non_pod_class || CLASSTYPE_NON_AGGREGATE (t)
+         || TYPE_HAS_DESTRUCTOR (t) || TYPE_HAS_ASSIGN_REF (t);
    TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t);
    TYPE_HAS_COMPLEX_ASSIGN_REF (t)
      |= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t);
Index: egcs/gcc/cp/tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/tree.c,v
retrieving revision 1.103
diff -c -3 -p -r1.103 tree.c
*** tree.c	1999/03/31 18:59:19	1.103
--- tree.c	1999/04/12 11:09:38
*************** int
*** 2673,2701 ****
  pod_type_p (t)
       tree t;
  {
-   tree f;
- 
    while (TREE_CODE (t) == ARRAY_TYPE)
      t = TREE_TYPE (t);
  
!   if (! IS_AGGR_TYPE (t))
      return 1;
! 
!   if (CLASSTYPE_NON_AGGREGATE (t)
!       || TYPE_HAS_COMPLEX_ASSIGN_REF (t)
!       || TYPE_HAS_DESTRUCTOR (t))
      return 0;
- 
-   for (f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f))
-     {
-       if (TREE_CODE (f) != FIELD_DECL)
- 	continue;
- 
-       if (TREE_CODE (TREE_TYPE (f)) == REFERENCE_TYPE
- 	  || TYPE_PTRMEMFUNC_P (TREE_TYPE (f))
- 	  || TYPE_PTRMEM_P (TREE_TYPE (f)))
- 	return 0;
-     }
- 
    return 1;
  }
--- 2673,2684 ----
  pod_type_p (t)
       tree t;
  {
    while (TREE_CODE (t) == ARRAY_TYPE)
      t = TREE_TYPE (t);
  
!   if (! CLASS_TYPE_P (t))
      return 1;
!   if (CLASSTYPE_NON_POD_P (t))
      return 0;
    return 1;
  }
Index: egcs/gcc/testsuite/g++.old-deja/g++.brendan/crash63.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.brendan/crash63.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 crash63.C
*** crash63.C	1998/12/16 21:24:20	1.2
--- crash63.C	1999/04/12 11:09:38
*************** class UnitList 
*** 12,15 ****
     UnitList (...);
     };
  
! UnitList unit_list (String("keV"));
--- 12,15 ----
     UnitList (...);
     };
  
! UnitList unit_list (String("keV")); // WARNING - cannot pass non-pod
Index: egcs/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.brendan/crash64.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 crash64.C
*** crash64.C	1998/12/16 21:24:21	1.2
--- crash64.C	1999/04/12 11:09:38
*************** struct metatype { int base_list; };
*** 16,19 ****
  
  static _type_desc _type_metatype("metatype", sizeof(metatype),
    (RF_Ptr)0, 0, 1, 1,
!   _im_pers_mem_spec( ((size_t)&((( metatype *)0)-> base_list )) , 1));
--- 16,19 ----
  
  static _type_desc _type_metatype("metatype", sizeof(metatype),
    (RF_Ptr)0, 0, 1, 1,
!   _im_pers_mem_spec( ((size_t)&((( metatype *)0)-> base_list )) , 1)); // WARNING - cannot pass non-pod
Index: egcs/gcc/testsuite/g++.old-deja/g++.brendan/overload8.C
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/testsuite/g++.old-deja/g++.brendan/overload8.C,v
retrieving revision 1.3
diff -c -3 -p -r1.3 overload8.C
*** overload8.C	1998/12/16 21:26:37	1.3
--- overload8.C	1999/04/12 11:09:38
*************** class Complex{public:double re,im;
*** 6,9 ****
  void zxcvbnm(int n,...){n=1;}
  int main(){complex c; Complex C;
  zxcvbnm(1,c);
! zxcvbnm(1,C);}
--- 6,9 ----
  void zxcvbnm(int n,...){n=1;}
  int main(){complex c; Complex C;
  zxcvbnm(1,c);
! zxcvbnm(1,C);} // WARNING - cannot pass non pod
egcs/gcc/cp/ChangeLog:
Mon Apr 12 10:24:13 BST 1999  Nathan Sidwell  <nathan@acm.org>

	* cp-tree.h (build_component_addr): Remove prototype.
	* typeck.c (build_component_addr): Make static. Remove MSG
	argument.
	(build_component_addr): Remove MSG parameter, clean up
	comment.
	(build_x_function_call): Use cp_error.
	(build_unary_op): Adjust call of build_component_addr.
	
Index: egcs/gcc/cp/cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.213
diff -c -3 -p -r1.213 cp-tree.h
*** cp-tree.h	1999/04/02 15:36:01	1.213
--- cp-tree.h	1999/04/12 11:19:20
*************** extern tree convert_arguments			PROTO((t
*** 3410,3416 ****
  extern tree build_x_binary_op			PROTO((enum tree_code, tree, tree));
  extern tree build_binary_op			PROTO((enum tree_code, tree, tree, int));
  extern tree build_binary_op_nodefault		PROTO((enum tree_code, tree, tree, enum tree_code));
- extern tree build_component_addr		PROTO((tree, tree, const char *));
  extern tree build_x_unary_op			PROTO((enum tree_code, tree));
  extern tree build_unary_op			PROTO((enum tree_code, tree, int));
  extern tree unary_complex_lvalue		PROTO((enum tree_code, tree));
--- 3410,3415 ----
Index: egcs/gcc/cp/typeck.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck.c,v
retrieving revision 1.150
diff -c -3 -p -r1.150 typeck.c
*** typeck.c	1999/04/02 15:36:57	1.150
--- typeck.c	1999/04/12 11:19:21
*************** static tree convert_sequence PROTO((tree
*** 55,60 ****
--- 55,61 ----
  #endif
  static tree lookup_anon_field PROTO((tree, tree));
  static tree pointer_diff PROTO((tree, tree, tree));
+ static tree build_component_addr PROTO((tree, tree));
  static tree qualify_type PROTO((tree, tree));
  static tree get_delta_difference PROTO((tree, tree, int));
  static int comp_cv_target_types PROTO((tree, tree, int));
*************** build_x_function_call (function, params,
*** 2685,2692 ****
  	{
  	  if (current_class_type == NULL_TREE)
  	    {
! 	      error ("object missing in call to method `%s'",
! 		     IDENTIFIER_POINTER (function));
  	      return error_mark_node;
  	    }
  	  /* Yow: call from a static member function.  */
--- 2686,2692 ----
  	{
  	  if (current_class_type == NULL_TREE)
  	    {
! 	      cp_error ("object missing in call to method `%D'", function);
  	      return error_mark_node;
  	    }
  	  /* Yow: call from a static member function.  */
*************** pointer_diff (op0, op1, ptrtype)
*** 4248,4264 ****
  }
  
  /* Handle the case of taking the address of a COMPONENT_REF.
!    Called by `build_unary_op' and `build_up_reference'.
  
     ARG is the COMPONENT_REF whose address we want.
!    ARGTYPE is the pointer type that this address should have.
!    MSG is an error message to print if this COMPONENT_REF is not
!    addressable (such as a bitfield).  */
  
! tree
! build_component_addr (arg, argtype, msg)
       tree arg, argtype;
-      const char *msg;
  {
    tree field = TREE_OPERAND (arg, 1);
    tree basetype = decl_type_context (field);
--- 4248,4261 ----
  }
  
  /* Handle the case of taking the address of a COMPONENT_REF.
!    Called by `build_unary_op'.
  
     ARG is the COMPONENT_REF whose address we want.
!    ARGTYPE is the pointer type that this address should have. */
  
! static tree
! build_component_addr (arg, argtype)
       tree arg, argtype;
  {
    tree field = TREE_OPERAND (arg, 1);
    tree basetype = decl_type_context (field);
*************** build_component_addr (arg, argtype, msg)
*** 4268,4274 ****
  
    if (DECL_C_BIT_FIELD (field))
      {
!       error (msg, IDENTIFIER_POINTER (DECL_NAME (field)));
        return error_mark_node;
      }
  
--- 4265,4272 ----
  
    if (DECL_C_BIT_FIELD (field))
      {
!       cp_error ("attempt to take address of bit-field structure member `%D'",
!                 field);
        return error_mark_node;
      }
  
*************** build_unary_op (code, xarg, noconvert)
*** 4731,4739 ****
  	tree addr;
  
  	if (TREE_CODE (arg) == COMPONENT_REF)
! 	  addr = build_component_addr
! 	    (arg, argtype,
! 	     "attempt to take address of bit-field structure member `%s'");
  	else
  	  addr = build1 (ADDR_EXPR, argtype, arg);
  
--- 4729,4735 ----
  	tree addr;
  
  	if (TREE_CODE (arg) == COMPONENT_REF)
! 	  addr = build_component_addr (arg, argtype);
  	else
  	  addr = build1 (ADDR_EXPR, argtype, arg);
  

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