OSDN Git Service

PR c++/25811
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Apr 2010 19:58:27 +0000 (19:58 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 00:58:07 +0000 (09:58 +0900)
* cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Declare.
* init.c (build_new_1): Check for uninitialized const members and
uninitialized reference members, when using new without
new-initializer. Call diagnose_uninitialized_cst_or_ref_member.
(diagnose_uninitialized_cst_or_ref_member): Define, call
diagnose_uninitialized_cst_or_ref_member_1.
(diagnose_uninitialized_cst_or_ref_member_1): New function.

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

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/testsuite/ChangeLog

index e56c77c..c32e19f 100644 (file)
@@ -1,3 +1,14 @@
+2010-04-12  Fabien Chene  <fabien.chene@gmail.com>
+
+       PR c++/25811
+       * cp-tree.h (diagnose_uninitialized_cst_or_ref_member): Declare.
+       * init.c (build_new_1): Check for uninitialized const members and
+       uninitialized reference members, when using new without
+       new-initializer. Call diagnose_uninitialized_cst_or_ref_member.
+       (diagnose_uninitialized_cst_or_ref_member): Define, call
+       diagnose_uninitialized_cst_or_ref_member_1.
+       (diagnose_uninitialized_cst_or_ref_member_1): New function.
+
 2010-04-12  Richard Guenther  <rguenther@suse.de>
 
        PR c++/43611
index 941c49a..91f2a9e 100644 (file)
@@ -1,6 +1,6 @@
 /* Definitions for C++ parsing and type checking.
    Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
@@ -4852,6 +4852,7 @@ extern tree create_temporary_var          (tree);
 extern void initialize_vtbl_ptrs               (tree);
 extern tree build_java_class_ref               (tree);
 extern tree integral_constant_value            (tree);
+extern void diagnose_uninitialized_cst_or_ref_member (tree, bool);
 
 /* in lex.c */
 extern void cxx_dup_lang_specific_decl         (tree);
index 1fb5eb0..c1f1cbf 100644 (file)
@@ -54,7 +54,7 @@ static tree dfs_initialize_vtbl_ptrs (tree, void *);
 static tree build_dtor_call (tree, special_function_kind, int);
 static tree build_field_list (tree, tree, int *);
 static tree build_vtbl_address (tree);
-static int diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool, bool);
+static void diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool);
 
 /* We are about to generate some complex initialization code.
    Conceptually, it is all a single expression.  However, we may want
@@ -506,7 +506,6 @@ perform_member_init (tree member, tree init)
     {
       if (init == NULL_TREE)
        {
-         tree core_type;
          /* member traversal: note it leaves init NULL */
          if (TREE_CODE (type) == REFERENCE_TYPE)
            permerror (DECL_SOURCE_LOCATION (current_function_decl),
@@ -516,14 +515,6 @@ perform_member_init (tree member, tree init)
            permerror (DECL_SOURCE_LOCATION (current_function_decl),
                       "uninitialized member %qD with %<const%> type %qT",
                       member, type);
-
-         core_type = strip_array_types (type);
-         if (CLASS_TYPE_P (core_type)
-             && (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)
-                 || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)))
-           diagnose_uninitialized_cst_or_ref_member (core_type,
-                                                     /*using_new=*/false,
-                                                     /*complain=*/true);
        }
       else if (TREE_CODE (init) == TREE_LIST)
        /* There was an explicit member initialization.  Do some work
@@ -1667,14 +1658,7 @@ constant_value_1 (tree decl, bool integral_p)
          init = DECL_INITIAL (decl);
        }
       if (init == error_mark_node)
-       {
-         if (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
-           /* Treat the error as a constant to avoid cascading errors on
-              excessively recursive template instantiation (c++/9335).  */
-           return init;
-         else
-           return decl;
-       }
+       return decl;
       /* Initializers in templates are generally expanded during
         instantiation, so before that for const int i(2)
         INIT is a TREE_LIST with the actual initializer as
@@ -1772,18 +1756,13 @@ build_raw_new_expr (VEC(tree,gc) *placement, tree type, tree nelts,
 
 /* Diagnose uninitialized const members or reference members of type
    TYPE. USING_NEW is used to disambiguate the diagnostic between a
-   new expression without a new-initializer and a declaration. Returns
-   the error count. */
+   new expression without a new-initializer and a declaration */
 
-static int
+static void
 diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin,
-                                           bool using_new, bool complain)
+                                           bool using_new)
 {
   tree field;
-  int error_count = 0;
-
-  if (type_has_user_provided_constructor (type))
-    return 0;
 
   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
     {
@@ -1796,46 +1775,36 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin,
 
       if (TREE_CODE (field_type) == REFERENCE_TYPE)
        {
-         ++ error_count;
-         if (complain)
-           {
-             if (using_new)
-               error ("uninitialized reference member in %q#T "
-                      "using %<new%> without new-initializer", origin);
-             else
-               error ("uninitialized reference member in %q#T", origin);
-             inform (DECL_SOURCE_LOCATION (field),
-                     "%qD should be initialized", field);
-           }
+         if (using_new)
+           error ("uninitialized reference member in %q#T using %<new%>",
+                  origin);
+         else
+           error ("uninitialized reference member in %q#T", origin);
+         inform (DECL_SOURCE_LOCATION (field),
+                 "%qD should be initialized", field);
        }
 
       if (CP_TYPE_CONST_P (field_type))
        {
-         ++ error_count;
-         if (complain)
-           {
-             if (using_new)
-               error ("uninitialized const member in %q#T "
-                      "using %<new%> without new-initializer", origin);
-             else
-               error ("uninitialized const member in %q#T", origin);
-             inform (DECL_SOURCE_LOCATION (field),
-                     "%qD should be initialized", field);
-           }
+         if (using_new)
+           error ("uninitialized const member in %q#T using %<new%>",
+                  origin);
+         else
+           error ("uninitialized const member in %q#T", origin);
+         inform (DECL_SOURCE_LOCATION (field),
+                 "%qD should be initialized", field);
        }
 
       if (CLASS_TYPE_P (field_type))
-       error_count
-         += diagnose_uninitialized_cst_or_ref_member_1 (field_type, origin,
-                                                        using_new, complain);
+       diagnose_uninitialized_cst_or_ref_member_1 (field_type,
+                                                   origin, using_new);
     }
-  return error_count;
 }
 
-int
-diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new, bool complain)
+void
+diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new)
 {
-  return diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new, complain);
+  diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new);
 }
 
 /* Generate code for a new-expression, including calling the "operator
@@ -1924,13 +1893,13 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
 
   is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL);
 
-  if (*init == NULL)
+  if (*init == NULL && !type_has_user_provided_constructor (elt_type))
     {
-      bool maybe_uninitialized_error = false;
+      bool uninitialized_error = false;
       /* A program that calls for default-initialization [...] of an
         entity of reference type is ill-formed. */
       if (CLASSTYPE_REF_FIELDS_NEED_INIT (elt_type))
-       maybe_uninitialized_error = true;
+       uninitialized_error = true;
 
       /* A new-expression that creates an object of type T initializes
         that object as follows:
@@ -1945,13 +1914,15 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
           const-qualified type, the program is ill-formed; */
 
       if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (elt_type))
-       maybe_uninitialized_error = true;
+       uninitialized_error = true;
 
-      if (maybe_uninitialized_error
-         && diagnose_uninitialized_cst_or_ref_member (elt_type,
-                                                      /*using_new=*/true,
-                                                      complain & tf_error))
-       return error_mark_node;
+      if (uninitialized_error)
+       {
+         if (complain & tf_error)
+           diagnose_uninitialized_cst_or_ref_member (elt_type,
+                                                     /*using_new*/true);
+         return error_mark_node;
+       }
     }
 
   if (CP_TYPE_CONST_P (elt_type) && *init == NULL
@@ -2200,7 +2171,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
   /* But we want to operate on a non-const version to start with,
      since we'll be modifying the elements.  */
   non_const_pointer_type = build_pointer_type
-    (cp_build_qualified_type (type, cp_type_quals (type) & ~TYPE_QUAL_CONST));
+    (cp_build_qualified_type (type, TYPE_QUALS (type) & ~TYPE_QUAL_CONST));
 
   data_addr = fold_convert (non_const_pointer_type, data_addr);
   /* Any further uses of alloc_node will want this type, too.  */
@@ -2476,7 +2447,6 @@ build_new (VEC(tree,gc) **placement, tree type, tree nelts,
           else
             return error_mark_node;
         }
-      nelts = mark_rvalue_use (nelts);
       nelts = cp_save_expr (cp_convert (sizetype, nelts));
     }
 
@@ -3132,8 +3102,6 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
 
   type = TYPE_MAIN_VARIANT (type);
 
-  addr = mark_rvalue_use (addr);
-
   if (TREE_CODE (type) == POINTER_TYPE)
     {
       bool complete_p = true;
index f6fb943..4b79ce0 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-12  Fabien Chene  <fabien.chene@gmail.com>
+
+       PR c++/25811
+       * g++.dg/init/pr25811.C: New test.
+
 2010-04-12  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
        * g++.dg/warn/miss-format-1.C: Removed *-*-solaris2.7 from