OSDN Git Service

PR c++/43890
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Apr 2010 04:23:00 +0000 (04:23 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 30 Apr 2010 04:23:00 +0000 (04:23 +0000)
* init.c (diagnose_uninitialized_cst_or_ref_member): check for
user-provided constructor while recursing.

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

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/pr43890.C [new file with mode: 0644]

index 03bf79b..58815e9 100644 (file)
@@ -1,3 +1,9 @@
+2010-04-29  Fabien Chêne  <fabien.chene@gmail.com>
+
+       PR c++/43890
+       * init.c (diagnose_uninitialized_cst_or_ref_member): check for
+       user-provided constructor while recursing.
+
 2010-04-28  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        PR c++/9335
index 5f0f665..70e3d38 100644 (file)
@@ -1779,6 +1779,9 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin,
 {
   tree field;
 
+  if (type_has_user_provided_constructor (type))
+    return;
+
   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
     {
       tree field_type;
@@ -1791,8 +1794,8 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin,
       if (TREE_CODE (field_type) == REFERENCE_TYPE)
        {
          if (using_new)
-           error ("uninitialized reference member in %q#T using %<new%>",
-                  origin);
+           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),
@@ -1802,8 +1805,8 @@ diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin,
       if (CP_TYPE_CONST_P (field_type))
        {
          if (using_new)
-           error ("uninitialized const member in %q#T using %<new%>",
-                  origin);
+           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),
@@ -1908,13 +1911,13 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
 
   is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL);
 
-  if (*init == NULL && !type_has_user_provided_constructor (elt_type))
+  if (*init == NULL)
     {
-      bool uninitialized_error = false;
+      bool maybe_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))
-       uninitialized_error = true;
+       maybe_uninitialized_error = true;
 
       /* A new-expression that creates an object of type T initializes
         that object as follows:
@@ -1929,9 +1932,9 @@ 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))
-       uninitialized_error = true;
+       maybe_uninitialized_error = true;
 
-      if (uninitialized_error)
+      if (maybe_uninitialized_error)
        {
          if (complain & tf_error)
            diagnose_uninitialized_cst_or_ref_member (elt_type,
index 7b9a134..9dfc098 100644 (file)
@@ -1,3 +1,9 @@
+2010-04-29  Fabien Chêne  <fabien.chene@gmail.com>
+
+       PR c++/43890
+       * init.c (diagnose_uninitialized_cst_or_ref_member): check for
+       user-provided constructor while recursing.
+
 2010-04-29  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/42274
diff --git a/gcc/testsuite/g++.dg/init/pr43890.C b/gcc/testsuite/g++.dg/init/pr43890.C
new file mode 100644 (file)
index 0000000..1b2807d
--- /dev/null
@@ -0,0 +1,39 @@
+// PR c++/43890
+// { dg-do compile }
+
+class Outer
+{
+  public:
+  Outer()
+  : i(*this)
+  {
+  }
+
+  class Inner
+  {
+    public:
+    Inner(Outer& o)
+    : o(o)
+    , i(0)
+    {
+    }
+
+    private:
+    Outer& o;
+    int const i;
+  };
+
+  private:
+  Inner i;
+};
+
+class A {
+  Outer o;
+};
+
+int main()
+{
+  A *a = new A;
+
+  return 0;
+}