PR c++/35782, c++/37860
authorJason Merrill <jason@redhat.com>
Tue, 2 Dec 2008 23:52:02 +0000 (18:52 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 2 Dec 2008 23:52:02 +0000 (18:52 -0500)
        PR c++/35782, c++/37860
        * call.c (build_user_type_conversion_1): Remember
        list-initialization.
        (convert_like_real): Likewise.
        (build_over_call): Don't require the copy constructor
        for copy-list-initialization.
        * cp-tree.h (TARGET_EXPR_LIST_INIT_P): New macro.

        PR c++/37234
        * decl.c (cp_finish_decl): Handle =default and =delete for
        templates, too.

From-SVN: r142379

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/defaulted5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/initlist9.C [new file with mode: 0644]

index 438b3e0..124dc3f 100644 (file)
@@ -1,3 +1,17 @@
+2008-12-02  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35782, c++/37860
+       * call.c (build_user_type_conversion_1): Remember
+       list-initialization.
+       (convert_like_real): Likewise.
+       (build_over_call): Don't require the copy constructor
+       for copy-list-initialization.
+       * cp-tree.h (TARGET_EXPR_LIST_INIT_P): New macro.
+
+       PR c++/37234
+       * decl.c (cp_finish_decl): Handle =default and =delete for
+       templates, too.
+
 2008-12-01  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/38257
index bbd6a22..273599e 100644 (file)
@@ -2871,6 +2871,10 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags)
      build_identity_conv (TREE_TYPE (expr), expr));
   conv->cand = cand;
 
+  /* Remember that this was a list-initialization.  */
+  if (flags & LOOKUP_NO_NARROWING)
+    conv->check_narrowing = true;
+
   /* Combine it with the second conversion sequence.  */
   cand->second_conv = merge_conversion_sequences (conv,
                                                  cand->second_conv);
@@ -4579,7 +4583,13 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
        /* If this is a constructor or a function returning an aggr type,
           we need to build up a TARGET_EXPR.  */
        if (DECL_CONSTRUCTOR_P (convfn))
-         expr = build_cplus_new (totype, expr);
+         {
+           expr = build_cplus_new (totype, expr);
+
+           /* Remember that this was list-initialization.  */
+           if (convs->check_narrowing)
+             TARGET_EXPR_LIST_INIT_P (expr) = true;
+         }
 
        return expr;
       }
@@ -5314,9 +5324,15 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
       else
        arg = cp_build_indirect_ref (arg, 0, complain);
 
+      if (TREE_CODE (arg) == TARGET_EXPR
+         && TARGET_EXPR_LIST_INIT_P (arg))
+       {
+         /* Copy-list-initialization doesn't require the copy constructor
+            to be defined.  */
+       }
       /* [class.copy]: the copy constructor is implicitly defined even if
         the implementation elided its use.  */
-      if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
+      else if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn)))
        {
          mark_used (fn);
          already_used = true;
index a03fe9b..7f33ff1 100644 (file)
@@ -89,6 +89,7 @@ framework extensions, you must include this file before toplev.h, not after.
       DECL_INITIALIZED_P (in VAR_DECL)
       TYPENAME_IS_CLASS_P (in TYPENAME_TYPE)
       STMT_IS_FULL_EXPR_P (in _STMT)
+      TARGET_EXPR_LIST_INIT_P (in TARGET_EXPR)
    2: IDENTIFIER_OPNAME_P (in IDENTIFIER_NODE)
       ICS_THIS_FLAG (in _CONV)
       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
@@ -3463,6 +3464,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 #define TARGET_EXPR_IMPLICIT_P(NODE) \
   TREE_LANG_FLAG_0 (TARGET_EXPR_CHECK (NODE))
 
+/* True if this TARGET_EXPR is the result of list-initialization of a
+   temporary.  */
+#define TARGET_EXPR_LIST_INIT_P(NODE) \
+  TREE_LANG_FLAG_1 (TARGET_EXPR_CHECK (NODE))
+
 /* An enumeration of the kind of tags that C++ accepts.  */
 enum tag_types {
   none_type = 0, /* Not a tag type.  */
index 997c580..d045935 100644 (file)
@@ -5504,6 +5504,25 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
        }
     }
 
+  if (init && TREE_CODE (decl) == FUNCTION_DECL)
+    {
+      if (init == ridpointers[(int)RID_DELETE])
+       {
+         /* FIXME check this is 1st decl.  */
+         DECL_DELETED_FN (decl) = 1;
+         DECL_DECLARED_INLINE_P (decl) = 1;
+         DECL_INITIAL (decl) = error_mark_node;
+         init = NULL_TREE;
+       }
+      else if (init == ridpointers[(int)RID_DEFAULT])
+       {
+         if (!defaultable_fn_p (decl))
+           error ("%qD cannot be defaulted", decl);
+         else
+           DECL_DEFAULTED_FN (decl) = 1;
+       }
+    }
+    
   if (processing_template_decl)
     {
       bool type_dependent_p;
@@ -5765,25 +5784,12 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
        {
          if (init)
            {
-             if (init == ridpointers[(int)RID_DELETE])
-               {
-                 /* fixme check this is 1st decl */
-                 DECL_DELETED_FN (decl) = 1;
-                 DECL_DECLARED_INLINE_P (decl) = 1;
-                 DECL_INITIAL (decl) = error_mark_node;
-               }
-             else if (init == ridpointers[(int)RID_DEFAULT])
+             if (init == ridpointers[(int)RID_DEFAULT])
                {
-                 if (!defaultable_fn_p (decl))
-                   error ("%qD cannot be defaulted", decl);
-                 else
-                   {
-                     /* An out-of-class default definition is defined at
-                        the point where it is explicitly defaulted.  */
-                     DECL_DEFAULTED_FN (decl) = 1;
-                     if (DECL_INITIAL (decl) == error_mark_node)
-                       synthesize_method (decl);
-                   }
+                 /* An out-of-class default definition is defined at
+                    the point where it is explicitly defaulted.  */
+                 if (DECL_INITIAL (decl) == error_mark_node)
+                   synthesize_method (decl);
                }
              else
                error ("function %q#D is initialized like a variable", decl);
index 77b69ee..6d585a6 100644 (file)
@@ -1,3 +1,11 @@
+2008-12-02  Jason Merrill  <jason@redhat.com>
+
+       PR c++/35782, c++/37860
+       * g++.dg/cpp0x/initlist9.C: New test.
+
+       PR c++/37234
+       * g++.dg/cpp0x/defaulted5.C: New test.
+
 2008-12-02  Jack Howarth  <howarth@bromo.med.uc.edu>
 
        * gcc.misc-tests/linkage.exp: Correct file type check for Darwin.
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted5.C b/gcc/testsuite/g++.dg/cpp0x/defaulted5.C
new file mode 100644 (file)
index 0000000..b7bd16b
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/37234
+// { dg-do link }
+// { dg-options "-std=c++0x" }
+
+template <typename T>
+class foo {
+  public:
+    foo() =default;
+    ~foo();
+};
+
+template <typename T>
+foo<T>::~foo() =default;
+
+int main() {
+
+    foo<int> fi;
+
+    return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist9.C b/gcc/testsuite/g++.dg/cpp0x/initlist9.C
new file mode 100644 (file)
index 0000000..61d87f9
--- /dev/null
@@ -0,0 +1,29 @@
+// PR c++/37860
+// { dg-options "-std=c++0x" }
+
+struct b
+{
+  bool t;
+
+  b() = default;
+  ~b() = default;
+  b& operator=(const b&) = delete;
+  b(const b&) = delete;
+
+  b(bool _t): t (_t) { }
+};
+
+int main()
+{
+  // copy list initialization
+  b tst1 = { false };
+
+  // copy initialization.
+  b tst2 = false;              // { dg-error "deleted" }
+
+  // direct list initialization
+  b tst3 { false };
+
+  // default initialization
+  b tst4;
+}