OSDN Git Service

* cp-tree.h (struct lang_type): Added non_zero_init.
authoraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 14 May 2002 17:20:47 +0000 (17:20 +0000)
committeraoliva <aoliva@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 14 May 2002 17:20:47 +0000 (17:20 +0000)
(CLASS_NON_ZERO_INIT_P): New macro.
(zero_init_p, force_store_init_value, build_forced_zero_init): Declare.
* class.c (check_field_decls): Test non_zero_init.
* cvt.c (convert_to_pointer_force): Use cp_convert_to_pointer for
zero-to-NULL conversions.
* decl.c (obscure_complex_init): Don't reset DECL_INITIAL of a
type that needs zero-initialization without zeros.
(check_initializer_decl): Compute zero-initializer for types
that require a non-trivial one.
* init.c (build_forced_zero_init): New function.
(build_default_init): Use it.
* tree.c (zero_init_p): New function.
* typeck2.c (force_store_init_value): New function.
(process_init_constructor): Create non-trivial zero-initializers
for array members and class fields.

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

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/decl.c
gcc/cp/init.c
gcc/cp/tree.c
gcc/cp/typeck2.c

index 12e90cf..b5dcccd 100644 (file)
@@ -1,3 +1,22 @@
+2002-05-14  Alexandre Oliva  <aoliva@redhat.com>
+
+       * cp-tree.h (struct lang_type): Added non_zero_init.
+       (CLASS_NON_ZERO_INIT_P): New macro.
+       (zero_init_p, force_store_init_value, build_forced_zero_init): Declare.
+       * class.c (check_field_decls): Test non_zero_init.
+       * cvt.c (convert_to_pointer_force): Use cp_convert_to_pointer for
+       zero-to-NULL conversions.
+       * decl.c (obscure_complex_init): Don't reset DECL_INITIAL of a
+       type that needs zero-initialization without zeros.
+       (check_initializer_decl): Compute zero-initializer for types
+       that require a non-trivial one.
+       * init.c (build_forced_zero_init): New function.
+       (build_default_init): Use it.
+       * tree.c (zero_init_p): New function.
+       * typeck2.c (force_store_init_value): New function.
+       (process_init_constructor): Create non-trivial zero-initializers
+       for array members and class fields.
+
 2002-05-14  Neil Booth  <neil@daikokuya.demon.co.uk>
 
        * lang-specs.h: Remove redundant -lang-c++.
index 98f32dc..64b528a 100644 (file)
@@ -3405,6 +3405,9 @@ check_field_decls (t, access_decls, empty_p,
            to be allowed in POD structs.  */
        CLASSTYPE_NON_POD_P (t) = 1;
 
+      if (! zero_init_p (type))
+       CLASSTYPE_NON_ZERO_INIT_P (t) = 1;
+
       /* If any field is const, the structure type is pseudo-const.  */
       if (CP_TYPE_CONST_P (type))
        {
index 0f2ad7c..a1d4ddb 100644 (file)
@@ -1240,6 +1240,8 @@ struct lang_type
   unsigned is_partial_instantiation : 1;
   unsigned java_interface : 1;
 
+  unsigned non_zero_init : 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!  */
@@ -1247,7 +1249,7 @@ struct lang_type
   /* There are some bits left to fill out a 32-bit word.  Keep track
      of this by updating the size of this bitfield whenever you add or
      remove a flag.  */
-  unsigned dummy : 8;
+  unsigned dummy : 7;
 
   int vsize;
 
@@ -1501,9 +1503,14 @@ struct lang_type
 #define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC (NODE)->has_mutable)
 #define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
 
-/*  Nonzero means that this class type is a non-POD class.  */
+/* Nonzero means that this class type is a non-POD class.  */
 #define CLASSTYPE_NON_POD_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_pod_class)
 
+/* Nonzero means that this class contains pod types whose default
+   initialization is not a zero initialization (namely, pointers to
+   data members).  */
+#define CLASSTYPE_NON_ZERO_INIT_P(NODE) (TYPE_LANG_SPECIFIC (NODE)->non_zero_init)
+
 /* Nonzero if this class is "nearly empty", i.e., contains only a
    virtual function table pointer.  */
 #define CLASSTYPE_NEARLY_EMPTY_P(NODE) \
@@ -3912,6 +3919,7 @@ extern tree build_init                            PARAMS ((tree, tree, int));
 extern int is_aggr_type                                PARAMS ((tree, int));
 extern tree get_aggr_from_typedef              PARAMS ((tree, int));
 extern tree get_type_value                     PARAMS ((tree));
+extern tree build_forced_zero_init             PARAMS ((tree));
 extern tree build_member_call                  PARAMS ((tree, tree, tree));
 extern tree build_offset_ref                   PARAMS ((tree, tree));
 extern tree resolve_offset_ref                 PARAMS ((tree));
@@ -4230,6 +4238,7 @@ extern tree cxx_unsave_expr_now           PARAMS ((tree));
 extern tree cxx_maybe_build_cleanup            PARAMS ((tree));
 extern void init_tree                          PARAMS ((void));
 extern int pod_type_p                          PARAMS ((tree));
+extern int zero_init_p                         PARAMS ((tree));
 extern tree canonical_type_variant              PARAMS ((tree));
 extern void unshare_base_binfos                        PARAMS ((tree));
 extern int member_p                            PARAMS ((tree));
@@ -4376,6 +4385,7 @@ extern int abstract_virtuals_error                PARAMS ((tree, tree));
 #define my_friendly_assert(EXP, N) (void) \
  (((EXP) == 0) ? (fancy_abort (__FILE__, __LINE__, __FUNCTION__), 0) : 0)
 
+extern tree force_store_init_value             PARAMS ((tree, tree));
 extern tree store_init_value                   PARAMS ((tree, tree));
 extern tree digest_init                                PARAMS ((tree, tree, tree *));
 extern tree build_scoped_ref                   PARAMS ((tree, tree, tree *));
index fc57dd3..0c43fc3 100644 (file)
@@ -1,6 +1,6 @@
 /* Language-level data type conversion for GNU C++.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -288,13 +288,6 @@ convert_to_pointer_force (type, expr)
   register tree intype = TREE_TYPE (expr);
   register enum tree_code form = TREE_CODE (intype);
   
-  if (integer_zerop (expr))
-    {
-      expr = build_int_2 (0, 0);
-      TREE_TYPE (expr) = type;
-      return expr;
-    }
-
   if (form == POINTER_TYPE)
     {
       intype = TYPE_MAIN_VARIANT (intype);
index c854cb7..6c5b979 100644 (file)
@@ -7592,7 +7592,13 @@ obscure_complex_init (decl, init)
                                 NULL_TREE);
   else
 #endif
-    DECL_INITIAL (decl) = error_mark_node;
+    {
+      if (zero_init_p (TREE_TYPE (decl)))
+       DECL_INITIAL (decl) = error_mark_node;
+      /* Otherwise, force_store_init_value will have already stored a
+        zero-init initializer in DECL_INITIAL, that should be
+        retained.  */
+    }
 
   return init;
 }
@@ -7838,8 +7844,16 @@ check_initializer (decl, init)
       if (init)
        init = obscure_complex_init (decl, init);
     }
+  else if (!DECL_EXTERNAL (decl) && !zero_init_p (type))
+    {
+      force_store_init_value (decl, build_forced_zero_init (type));
+
+      if (init)
+       goto process_init;
+    }
   else if (init)
     {
+    process_init:
       if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))
        {
          if (TREE_CODE (type) == ARRAY_TYPE)
index 49ecf7c..9827307 100644 (file)
@@ -1,6 +1,6 @@
 /* Handle initialization things in C++.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -156,6 +156,44 @@ initialize_vtbl_ptrs (addr)
            dfs_marked_real_bases_queue_p, type);
 }
 
+/* Types containing pointers to data members cannot be
+   zero-initialized with zeros, because the NULL value for such
+   pointers is -1.
+
+   TYPE is a type that requires such zero initialization.  The
+   returned value is the initializer.  */
+
+tree
+build_forced_zero_init (type)
+     tree type;
+{
+  tree init = NULL;
+
+  if (AGGREGATE_TYPE_P (type) && !TYPE_PTRMEMFUNC_P (type))
+    {
+      /* This is a default initialization of an aggregate, but not one of
+        non-POD class type.  We cleverly notice that the initialization
+        rules in such a case are the same as for initialization with an
+        empty brace-initialization list.  */
+      init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
+    }
+  else if (TREE_CODE (type) == REFERENCE_TYPE)
+    /*   --if T is a reference type, no initialization is performed.  */
+    return NULL_TREE;
+  else
+    {
+      init = integer_zero_node;
+      
+      if (TREE_CODE (type) == ENUMERAL_TYPE)
+        /* We must make enumeral types the right type. */
+        init = fold (build1 (NOP_EXPR, type, init));
+    }
+
+  init = digest_init (type, init, 0);
+
+  return init;
+}
+
 /* [dcl.init]:
 
   To default-initialize an object of type T means:
@@ -182,28 +220,8 @@ build_default_init (type)
        anything with a CONSTRUCTOR for arrays here, as that would imply
        copy-initialization.  */
     return NULL_TREE;
-  else if (AGGREGATE_TYPE_P (type) && !TYPE_PTRMEMFUNC_P (type))
-    {
-      /* This is a default initialization of an aggregate, but not one of
-        non-POD class type.  We cleverly notice that the initialization
-        rules in such a case are the same as for initialization with an
-        empty brace-initialization list.  */
-      init = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
-    }
-  else if (TREE_CODE (type) == REFERENCE_TYPE)
-    /*   --if T is a reference type, no initialization is performed.  */
-    return NULL_TREE;
-  else
-    {
-      init = integer_zero_node;
-      
-      if (TREE_CODE (type) == ENUMERAL_TYPE)
-        /* We must make enumeral types the right type. */
-        init = fold (build1 (NOP_EXPR, type, init));
-    }
 
-  init = digest_init (type, init, 0);
-  return init;
+  return build_forced_zero_init (type);
 }
 
 /* Subroutine of emit_base_init.  */
index 02d5a4b..9a52cc0 100644 (file)
@@ -1,6 +1,6 @@
 /* Language-dependent node constructors for parse phase of GNU compiler.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -1901,6 +1901,27 @@ pod_type_p (t)
   return 1;
 }
 
+/* Returns 1 iff zero initialization of type T means actually storing
+   zeros in it.  */
+
+int
+zero_init_p (t)
+     tree t;
+{
+  t = strip_array_types (t);
+
+  /* NULL pointers to data members are initialized with -1.  */
+  if (TYPE_PTRMEM_P (t))
+    return 0;
+
+  /* Classes that contain types that can't be zero-initialized, cannot
+     be zero-initialized themselves.  */
+  if (CLASS_TYPE_P (t) && CLASSTYPE_NON_ZERO_INIT_P (t))
+    return 0;
+
+  return 1;
+}
+
 /* Table of valid C++ attributes.  */
 const struct attribute_spec cxx_attribute_table[] =
 {
index 38daa08..b837503 100644 (file)
@@ -1,7 +1,7 @@
 /* Report error messages, build initializers, and perform
    some front-end optimizations for C++ compiler.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -420,6 +420,28 @@ store_init_value (decl, init)
   DECL_INITIAL (decl) = value;
   return NULL_TREE;
 }
+
+/* Same as store_init_value, but used for known-to-be-valid static
+   initializers.  Used to introduce a static initializer even in data
+   structures that may require dynamic initialization.  */
+
+tree
+force_store_init_value (decl, init)
+     tree decl, init;
+{
+  tree type = TREE_TYPE (decl);
+  int needs_constructing = TYPE_NEEDS_CONSTRUCTING (type);
+
+  TYPE_NEEDS_CONSTRUCTING (type) = 0;
+
+  init = store_init_value (decl, init);
+  if (init)
+    abort ();
+
+  TYPE_NEEDS_CONSTRUCTING (type) = needs_constructing;
+
+  return init;
+}  
 \f
 /* Digest the parser output INIT as an initializer for type TYPE.
    Return a C expression of type TYPE to represent the initial value.
@@ -732,6 +754,8 @@ process_init_constructor (type, init, elts)
                next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE);
              next1 = digest_init (TREE_TYPE (type), next1, 0);
            }
+         else if (! zero_init_p (TREE_TYPE (type)))
+           next1 = build_forced_zero_init (TREE_TYPE (type));
          else
            /* The default zero-initialization is fine for us; don't
               add anything to the CONSTRUCTOR.  */
@@ -848,9 +872,12 @@ process_init_constructor (type, init, elts)
                  && (!init || TREE_HAS_CONSTRUCTOR (init)))
                warning ("missing initializer for member `%D'", field);
 
-             /* The default zero-initialization is fine for us; don't
-                add anything to the CONSTRUCTOR.  */
-             continue;
+             if (! zero_init_p (TREE_TYPE (field)))
+               next1 = build_forced_zero_init (TREE_TYPE (field));
+             else
+               /* The default zero-initialization is fine for us; don't
+                  add anything to the CONSTRUCTOR.  */
+               continue;
            }
 
          if (next1 == error_mark_node)