OSDN Git Service

* call.c (convert_arg_to_ellipsis): Use pod_type_p.
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Aug 1999 15:04:49 +0000 (15:04 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 3 Aug 1999 15:04:49 +0000 (15:04 +0000)
        * 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): Detect non-pod non-aggregate types.
        Use CLASSTYPE_NON_POD_P.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@28475 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/tree.c

index 5f589da..74bde45 100644 (file)
@@ -1,5 +1,16 @@
 1999-08-03  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): Detect non-pod non-aggregate types.
+       Use CLASSTYPE_NON_POD_P.
+
+1999-08-03  Nathan Sidwell  <nathan@acm.org>
+
        * class.c (duplicate_tag_error): Preserve template information.
 
 1999-08-03  Nathan Sidwell  <nathan@acm.org>
index 9cdfc75..fb8f129 100644 (file)
@@ -3752,21 +3752,25 @@ convert_like (convs, expr)
 }
 
 /* ARG is being passed to a varargs function.  Perform any conversions
-   required.  Return the converted value.  */
+   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 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);
index 78ed032..8ba5694 100644 (file)
@@ -3297,6 +3297,7 @@ finish_struct_1 (t)
   int no_const_asn_ref;
   int has_mutable = 0;
   int n_fields = 0;
+  int non_pod_class = 0;
 
   /* The index of the first base class which has virtual
      functions.  Only applied to non-virtual baseclasses.  */
@@ -3431,6 +3432,7 @@ finish_struct_1 (t)
   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)
@@ -3472,21 +3474,24 @@ finish_struct_1 (t)
 
       /* Perform error checking that did not get done in
         grokdeclarator.  */
-      if (TREE_CODE (TREE_TYPE (x)) == FUNCTION_TYPE)
+      if (TREE_CODE (type) == FUNCTION_TYPE)
        {
          cp_error_at ("field `%D' invalidly declared function type",
                       x);
-         TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
+         type = build_pointer_type (type);
+         TREE_TYPE (x) = type;
        }
-      else if (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE)
+      else if (TREE_CODE (type) == METHOD_TYPE)
        {
          cp_error_at ("field `%D' invalidly declared method type", x);
-         TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
+         type = build_pointer_type (type);
+         TREE_TYPE (x) = type;
        }
-      else if (TREE_CODE (TREE_TYPE (x)) == OFFSET_TYPE)
+      else if (TREE_CODE (type) == OFFSET_TYPE)
        {
          cp_error_at ("field `%D' invalidly declared offset type", x);
-         TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x));
+         type = build_pointer_type (type);
+         TREE_TYPE (x) = type;
        }
 
 #if 0
@@ -3494,7 +3499,7 @@ finish_struct_1 (t)
        cant_have_default_ctor = 1;
 #endif
 
-      if (TREE_TYPE (x) == error_mark_node)
+      if (type == error_mark_node)
        continue;
          
       DECL_SAVED_INSNS (x) = NULL_RTX;
@@ -3522,8 +3527,10 @@ finish_struct_1 (t)
 
       /* If this is of reference type, check if it needs an init.
         Also do a little ANSI jig if necessary.  */
-      if (TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE)
+      if (TREE_CODE (type) == REFERENCE_TYPE)
        {
+          non_pod_class = 1;
+          
          if (DECL_INITIAL (x) == NULL_TREE)
            ref_sans_init = 1;
 
@@ -3543,14 +3550,21 @@ finish_struct_1 (t)
            }
        }
 
-      if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
+      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 (TREE_TYPE (x)))
+      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 (CP_TYPE_CONST_P (TREE_TYPE (x)))
+      if (CP_TYPE_CONST_P (type))
        {
          C_TYPE_FIELDS_READONLY (t) = 1;
          if (DECL_INITIAL (x) == NULL_TREE)
@@ -3576,14 +3590,11 @@ finish_struct_1 (t)
        {
          /* 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 (IS_AGGR_TYPE (type))
            {
-             if (C_TYPE_FIELDS_READONLY (t1))
+             if (C_TYPE_FIELDS_READONLY (type))
                C_TYPE_FIELDS_READONLY (t) = 1;
-             if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (t1))
+             if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))
                const_sans_init = 1;
            }
        }
@@ -3593,7 +3604,10 @@ finish_struct_1 (t)
       if (DECL_C_BIT_FIELD (x))
        {
          /* Invalid bit-field size done by grokfield.  */
-         /* Detect invalid bit-field type.  */
+         /* Detect invalid bit-field type. Simply checking if TYPE is
+             integral is insufficient, as that is the array core of the
+             field type. If TREE_TYPE (x) is integral, then TYPE must be
+             the same.  */
          if (DECL_INITIAL (x)
              && ! INTEGRAL_TYPE_P (TREE_TYPE (x)))
            {
@@ -3643,20 +3657,20 @@ finish_struct_1 (t)
                         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)
+             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 (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)))
+             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, TREE_TYPE (x));
+                                x, type);
                }
 
              if (DECL_INITIAL (x))
@@ -3674,22 +3688,17 @@ finish_struct_1 (t)
 #ifdef PCC_BITFIELD_TYPE_MATTERS
                      if (PCC_BITFIELD_TYPE_MATTERS)
                        DECL_ALIGN (x) = MAX (DECL_ALIGN (x),
-                                             TYPE_ALIGN (TREE_TYPE (x)));
+                                             TYPE_ALIGN (type));
 #endif
                    }
                }
            }
          else
            /* Non-bit-fields are aligned for their type.  */
-           DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (TREE_TYPE (x)));
+           DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (type));
        }
       else
        {
-         tree type = TREE_TYPE (x);
-
-         while (TREE_CODE (type) == ARRAY_TYPE)
-           type = TREE_TYPE (type);
-
          if (CLASS_TYPE_P (type) && ! ANON_AGGR_TYPE_P (type))
            {
              /* Never let anything with uninheritable virtuals
@@ -3792,6 +3801,9 @@ finish_struct_1 (t)
   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 c5af6fd..31e9f8c 100644 (file)
@@ -802,6 +802,7 @@ struct lang_type
       unsigned is_partial_instantiation : 1;
       unsigned has_mutable : 1;
       unsigned com_interface : 1;
+      unsigned non_pod_class : 1;
       /* When adding a flag here, consider whether or not it ought to
         apply to a template instance if it applies to the template.
         If so, make sure to copy it in instantiate_class_template!  */
@@ -809,7 +810,7 @@ struct lang_type
       /* 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;
+      unsigned dummy : 9;
     } type_flags;
 
   int vsize;
@@ -1076,6 +1077,9 @@ struct lang_type
 #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)
+
 /* Nonzero means that this type is meant for communication via COM.  */
 #define CLASSTYPE_COM_INTERFACE(NODE) \
   (TYPE_LANG_SPECIFIC(NODE)->type_flags.com_interface)
index 9076cc7..ab71470 100644 (file)
@@ -2749,30 +2749,24 @@ int
 pod_type_p (t)
      tree t;
 {
-  tree f;
-
   while (TREE_CODE (t) == ARRAY_TYPE)
     t = TREE_TYPE (t);
 
-  if (! IS_AGGR_TYPE (t))
+  if (INTEGRAL_TYPE_P (t))
+    return 1;  /* integral, character or enumeral type */
+  if (FLOAT_TYPE_P (t))
     return 1;
-
-  if (CLASSTYPE_NON_AGGREGATE (t)
-      || TYPE_HAS_COMPLEX_ASSIGN_REF (t)
-      || TYPE_HAS_DESTRUCTOR (t))
+  if (TYPE_PTR_P (t))
+    return 1; /* pointer to non-member */
+  if (TYPE_PTRMEM_P (t))
+    return 1; /* pointer to member object */
+  if (TYPE_PTRMEMFUNC_P (t))
+    return 1; /* pointer to member function */
+  
+  if (! CLASS_TYPE_P (t))
+    return 0; /* other non-class type (reference or function) */
+  if (CLASSTYPE_NON_POD_P (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;
 }