]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
In C++11 a trivial [cd]tor might not be callable.
authorJason Merrill <jason@redhat.com>
Wed, 23 Oct 2013 18:08:56 +0000 (14:08 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 23 Oct 2013 18:08:56 +0000 (14:08 -0400)
* class.c (user_provided_p): A function deleted on its declation
in the class is not user-provided.
(type_build_ctor_call): Also force a ctor call if we
might have a deleted or private trivial ctor.
(type_build_dtor_call): New.
(deduce_noexcept_on_destructors): Remove obsolete code.
* cp-tree.h: Declare type_build_dtor_call.
* decl.c (expand_static_init): Make sure trivial dtors are callable.
(cxx_maybe_build_cleanup): Likewise.
* except.c (build_throw): Likewise.
* init.c (build_value_init): Handle trivial but not callable ctors.
(perform_target_ctor): Make sure trivial dtor is callable.
(perform_member_init): Likewise.
(expand_cleanup_for_base): Likewise.
(build_vec_delete_1): Likewise.
(build_delete): Likewise.
(push_base_cleanups): Likewise.
(build_new_1): Avoid redundant error.
* method.c (synthesized_method_walk): Can't ever exit early in C++11.
Always process the subobject destructor.
* semantics.c (finish_compound_literal): Make sure trivial dtor is
callable.
* typeck2.c (split_nonconstant_init): Likewise.

From-SVN: r203985

24 files changed:
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/except.c
gcc/cp/init.c
gcc/cp/method.c
gcc/cp/semantics.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/cpp0x/defaulted19.C
gcc/testsuite/g++.dg/cpp0x/defaulted19a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/defaulted2.C
gcc/testsuite/g++.dg/cpp0x/defaulted46.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/implicit11.C
gcc/testsuite/g++.dg/cpp0x/sfinae21.C
gcc/testsuite/g++.dg/ext/anon-struct4.C
gcc/testsuite/g++.dg/init/ctor8.C
gcc/testsuite/g++.dg/init/pr25811.C
gcc/testsuite/g++.dg/init/pr29043.C
gcc/testsuite/g++.dg/init/pr43719.C
gcc/testsuite/g++.dg/init/pr44086.C
gcc/testsuite/g++.dg/init/ref14.C
gcc/testsuite/g++.dg/init/uninitialized1.C

index c17e19d75f32a60c5f0161003bb6977640289e43..99269af9c6f0e6246d186256ab2bef8c1d8df3fb 100644 (file)
@@ -1,3 +1,30 @@
+2013-10-23  Jason Merrill  <jason@redhat.com>
+
+       In C++11 a trivial [cd]tor might not be callable.
+       * class.c (user_provided_p): A function deleted on its declation
+       in the class is not user-provided.
+       (type_build_ctor_call): Also force a ctor call if we
+       might have a deleted or private trivial ctor.
+       (type_build_dtor_call): New.
+       (deduce_noexcept_on_destructors): Remove obsolete code.
+       * cp-tree.h: Declare type_build_dtor_call.
+       * decl.c (expand_static_init): Make sure trivial dtors are callable.
+       (cxx_maybe_build_cleanup): Likewise.
+       * except.c (build_throw): Likewise.
+       * init.c (build_value_init): Handle trivial but not callable ctors.
+       (perform_target_ctor): Make sure trivial dtor is callable.
+       (perform_member_init): Likewise.
+       (expand_cleanup_for_base): Likewise.
+       (build_vec_delete_1): Likewise.
+       (build_delete): Likewise.
+       (push_base_cleanups): Likewise.
+       (build_new_1): Avoid redundant error.
+       * method.c (synthesized_method_walk): Can't ever exit early in C++11.
+       Always process the subobject destructor.
+       * semantics.c (finish_compound_literal): Make sure trivial dtor is
+       callable.
+       * typeck2.c (split_nonconstant_init): Likewise.
+
 2013-10-23  Edward Smith-Rowland  <3dw4rd@verizon.net>
 
        Implement C++14 [[deprecated]] modulo [[gnu::deprecated]] bugs.
index 3ed73b803740ce16990eb3b62a0baaff68cd5709..cd901409e909ebe9a90d04cd9953a64475baf3d2 100644 (file)
@@ -9273,6 +9273,9 @@ set_up_extended_ref_temp (tree decl, tree expr, vec<tree, va_gc> **cleanups,
            static_aggregates = tree_cons (NULL_TREE, var,
                                           static_aggregates);
        }
+      else
+       /* Check whether the dtor is callable.  */
+       cxx_maybe_build_cleanup (var, tf_warning_or_error);
     }
 
   *initp = init;
index c587e55ac6815e178c34ce2bdd53ee005f1f5384..43f90d7211824de6379b862ad30b95aa86c7beae 100644 (file)
@@ -4674,15 +4674,8 @@ deduce_noexcept_on_destructors (tree t)
   if (!CLASSTYPE_METHOD_VEC (t))
     return;
 
-  bool saved_nontrivial_dtor = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t);
-
-  /* Avoid early exit from synthesized_method_walk (c++/57645).  */
-  TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = true;
-
   for (tree fns = CLASSTYPE_DESTRUCTORS (t); fns; fns = OVL_NEXT (fns))
     deduce_noexcept_on_destructor (OVL_CURRENT (fns));
-
-  TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = saved_nontrivial_dtor;
 }
 
 /* Subroutine of set_one_vmethod_tm_attributes.  Search base classes
@@ -4884,7 +4877,8 @@ user_provided_p (tree fn)
     return true;
   else
     return (!DECL_ARTIFICIAL (fn)
-           && !DECL_DEFAULTED_IN_CLASS_P (fn));
+           && !(DECL_INITIALIZED_IN_CLASS_P (fn)
+                && (DECL_DEFAULTED_FN (fn) || DECL_DELETED_FN (fn))));
 }
 
 /* Returns true iff class T has a user-provided constructor.  */
@@ -5149,7 +5143,7 @@ type_has_user_declared_move_assign (tree t)
 }
 
 /* Nonzero if we need to build up a constructor call when initializing an
-   object of this class, either because it has a user-provided constructor
+   object of this class, either because it has a user-declared constructor
    or because it doesn't have a default constructor (so we need to give an
    error if no initializer is provided).  Use TYPE_NEEDS_CONSTRUCTING when
    what you care about is whether or not an object can be produced by a
@@ -5165,8 +5159,46 @@ type_build_ctor_call (tree t)
   if (TYPE_NEEDS_CONSTRUCTING (t))
     return true;
   inner = strip_array_types (t);
-  return (CLASS_TYPE_P (inner) && !TYPE_HAS_DEFAULT_CONSTRUCTOR (inner)
-         && !ANON_AGGR_TYPE_P (inner));
+  if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner))
+    return false;
+  if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (inner))
+    return true;
+  /* A user-declared constructor might be private, and a constructor might
+     be trivial but deleted.  */
+  for (tree fns = lookup_fnfields_slot (inner, complete_ctor_identifier);
+       fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+      if (!DECL_ARTIFICIAL (fn)
+         || DECL_DELETED_FN (fn))
+       return true;
+    }
+  return false;
+}
+
+/* Like type_build_ctor_call, but for destructors.  */
+
+bool
+type_build_dtor_call (tree t)
+{
+  tree inner;
+  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t))
+    return true;
+  inner = strip_array_types (t);
+  if (!CLASS_TYPE_P (inner) || ANON_AGGR_TYPE_P (inner)
+      || !COMPLETE_TYPE_P (inner))
+    return false;
+  /* A user-declared destructor might be private, and a destructor might
+     be trivial but deleted.  */
+  for (tree fns = lookup_fnfields_slot (inner, complete_dtor_identifier);
+       fns; fns = OVL_NEXT (fns))
+    {
+      tree fn = OVL_CURRENT (fns);
+      if (!DECL_ARTIFICIAL (fn)
+         || DECL_DELETED_FN (fn))
+       return true;
+    }
+  return false;
 }
 
 /* Remove all zero-width bit-fields from T.  */
index b1347e20dd6c764791e948bf25e459abea3132e2..507b3897aee3fa342e9207599436cf0377ba7a8c 100644 (file)
@@ -5115,6 +5115,7 @@ extern bool type_has_move_assign          (tree);
 extern bool type_has_user_declared_move_constructor (tree);
 extern bool type_has_user_declared_move_assign(tree);
 extern bool type_build_ctor_call               (tree);
+extern bool type_build_dtor_call               (tree);
 extern void explain_non_literal_class          (tree);
 extern void defaulted_late_check               (tree);
 extern bool defaultable_fn_check               (tree);
index fe8fe4ee52c15c59b2475fc8cc28f775204d9d7d..1e92f2af85e7dd1e718edb70f7826f5616ca7815 100644 (file)
@@ -6897,7 +6897,11 @@ expand_static_init (tree decl, tree init)
   /* Some variables require no dynamic initialization.  */
   if (!init
       && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
-    return;
+    {
+      /* Make sure the destructor is callable.  */
+      cxx_maybe_build_cleanup (decl, tf_warning_or_error);
+      return;
+    }
 
   if (DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
       && !DECL_FUNCTION_SCOPE_P (decl))
@@ -14296,7 +14300,7 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
     }
   /* Handle ordinary C++ destructors.  */
   type = TREE_TYPE (decl);
-  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+  if (type_build_dtor_call (type))
     {
       int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
       bool has_vbases = (TREE_CODE (type) == RECORD_TYPE
@@ -14317,6 +14321,8 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
                           sfk_complete_destructor, flags, 0, complain);
       if (call == error_mark_node)
        cleanup = error_mark_node;
+      else if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+       /* Discard the call.  */;
       else if (cleanup)
        cleanup = cp_build_compound_expr (cleanup, call, complain);
       else
index c76d9440aa9ece1f067d37efe55317e1a982d132..daac0fde7e6b2e9bc51f8956a1282cc9cac89b2e 100644 (file)
@@ -868,17 +868,21 @@ build_throw (tree exp)
 
       throw_type = build_eh_type_type (prepare_eh_type (TREE_TYPE (object)));
 
-      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
+      cleanup = NULL_TREE;
+      if (type_build_dtor_call (TREE_TYPE (object)))
        {
-         cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
+         tree fn = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)),
                                     complete_dtor_identifier, 0);
-         cleanup = BASELINK_FUNCTIONS (cleanup);
-         mark_used (cleanup);
-         cxx_mark_addressable (cleanup);
-         /* Pretend it's a normal function.  */
-         cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup);
+         fn = BASELINK_FUNCTIONS (fn);
+         mark_used (fn);
+         if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object)))
+           {
+             cxx_mark_addressable (fn);
+             /* Pretend it's a normal function.  */
+             cleanup = build1 (ADDR_EXPR, cleanup_type, fn);
+           }
        }
-      else
+      if (cleanup == NULL_TREE)
        cleanup = build_int_cst (cleanup_type, 0);
 
       /* ??? Indicate that this function call throws throw_type.  */
index d18dc5e8deb900c87cdcfe053c43ec90d709cf30..78ea986a0d6b97b40a7d374a20c0e6e69608b7f5 100644 (file)
@@ -312,60 +312,55 @@ build_value_init (tree type, tsubst_flags_t complain)
 
      To value-initialize an object of type T means:
 
-     - if T is a class type (clause 9) with a user-provided constructor
-       (12.1), then the default constructor for T is called (and the
-       initialization is ill-formed if T has no accessible default
-       constructor);
+     - if T is a class type (clause 9) with either no default constructor
+       (12.1) or a default constructor that is user-provided or deleted,
+       then then the object is default-initialized;
 
-     - if T is a non-union class type without a user-provided constructor,
-       then every non-static data member and base-class component of T is
-       value-initialized;92)
+     - if T is a (possibly cv-qualified) class type without a user-provided
+       or deleted default constructor, then the object is zero-initialized
+       and the semantic constraints for default-initialization are checked,
+       and if T has a non-trivial default constructor, the object is
+       default-initialized;
 
      - if T is an array type, then each element is value-initialized;
 
      - otherwise, the object is zero-initialized.
 
      A program that calls for default-initialization or
-     value-initialization of an entity of reference type is ill-formed.
-
-     92) Value-initialization for such a class object may be implemented by
-     zero-initializing the object and then calling the default
-     constructor.  */
+     value-initialization of an entity of reference type is ill-formed.  */
 
   /* The AGGR_INIT_EXPR tweaking below breaks in templates.  */
   gcc_assert (!processing_template_decl
              || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));
 
-  if (CLASS_TYPE_P (type))
+  if (type_build_ctor_call (type))
     {
-      /* Instead of the above, only consider the user-providedness of the
-        default constructor itself so value-initializing a class with an
-        explicitly defaulted default constructor and another user-provided
-        constructor works properly (c++std-core-19883).  */
-      if (type_has_user_provided_default_constructor (type)
-         || (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)
-             && type_has_user_provided_constructor (type)))
-       return build_aggr_init_expr
-         (type,
-          build_special_member_call (NULL_TREE, complete_ctor_identifier,
-                                     NULL, type, LOOKUP_NORMAL,
-                                     complain));
+      tree ctor = build_aggr_init_expr
+       (type,
+        build_special_member_call (NULL_TREE, complete_ctor_identifier,
+                                   NULL, type, LOOKUP_NORMAL,
+                                   complain));
+      if (ctor == error_mark_node
+         || type_has_user_provided_default_constructor (type))
+       return ctor;
       else if (TYPE_HAS_COMPLEX_DFLT (type))
        {
          /* This is a class that needs constructing, but doesn't have
             a user-provided constructor.  So we need to zero-initialize
             the object and then call the implicitly defined ctor.
             This will be handled in simplify_aggr_init_expr.  */
-         tree ctor = build_special_member_call
-           (NULL_TREE, complete_ctor_identifier,
-            NULL, type, LOOKUP_NORMAL, complain);
-         ctor = build_aggr_init_expr (type, ctor);
-         if (ctor != error_mark_node)
-           AGGR_INIT_ZERO_FIRST (ctor) = 1;
+         AGGR_INIT_ZERO_FIRST (ctor) = 1;
          return ctor;
        }
     }
-  return build_value_init_noctor (type, complain);
+
+  /* Discard any access checking during subobject initialization;
+     the checks are implied by the call to the ctor which we have
+     verified is OK (cpp0x/defaulted46.C).  */
+  push_deferring_access_checks (dk_deferred);
+  tree r = build_value_init_noctor (type, complain);
+  pop_deferring_access_checks ();
+  return r;
 }
 
 /* Like build_value_init, but don't call the constructor for TYPE.  Used
@@ -503,14 +498,15 @@ perform_target_ctor (tree init)
   finish_expr_stmt (build_aggr_init (decl, init,
                                     LOOKUP_NORMAL|LOOKUP_DELEGATING_CONS,
                                     tf_warning_or_error));
-  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+  if (type_build_dtor_call (type))
     {
       tree expr = build_delete (type, decl, sfk_complete_destructor,
                                LOOKUP_NORMAL
                                |LOOKUP_NONVIRTUAL
                                |LOOKUP_DESTRUCTOR,
                                0, tf_warning_or_error);
-      if (expr != error_mark_node)
+      if (expr != error_mark_node
+         && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
        finish_eh_cleanup (expr);
     }
 }
@@ -732,7 +728,7 @@ perform_member_init (tree member, tree init)
                                                tf_warning_or_error));
     }
 
-  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+  if (type_build_dtor_call (type))
     {
       tree expr;
 
@@ -744,7 +740,8 @@ perform_member_init (tree member, tree init)
                           LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0,
                           tf_warning_or_error);
 
-      if (expr != error_mark_node)
+      if (expr != error_mark_node
+         && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
        finish_eh_cleanup (expr);
     }
 }
@@ -1192,7 +1189,7 @@ expand_cleanup_for_base (tree binfo, tree flag)
 {
   tree expr;
 
-  if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (binfo)))
+  if (!type_build_dtor_call (BINFO_TYPE (binfo)))
     return;
 
   /* Call the destructor.  */
@@ -1202,6 +1199,10 @@ expand_cleanup_for_base (tree binfo, tree flag)
                                    binfo,
                                    LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
                                     tf_warning_or_error);
+
+  if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (binfo)))
+    return;
+
   if (flag)
     expr = fold_build3_loc (input_location,
                        COND_EXPR, void_type_node,
@@ -2360,7 +2361,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 
   is_initialized = (type_build_ctor_call (elt_type) || *init != NULL);
 
-  if (*init == NULL)
+  if (*init == NULL && cxx_dialect < cxx11)
     {
       bool maybe_uninitialized_error = false;
       /* A program that calls for default-initialization [...] of an
@@ -3152,8 +3153,21 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
 
   size_exp = size_in_bytes (type);
 
-  if (! MAYBE_CLASS_TYPE_P (type) || TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+  if (! MAYBE_CLASS_TYPE_P (type))
     goto no_destructor;
+  else if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
+    {
+      /* Make sure the destructor is callable.  */
+      if (type_build_dtor_call (type))
+       {
+         tmp = build_delete (ptype, base, sfk_complete_destructor,
+                             LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1,
+                             complain);
+         if (tmp == error_mark_node)
+           return error_mark_node;
+       }
+      goto no_destructor;
+    }
 
   /* The below is short by the cookie size.  */
   virtual_size = size_binop (MULT_EXPR, size_exp,
@@ -3829,7 +3843,7 @@ build_dtor_call (tree exp, special_function_kind dtor_kind, int flags,
    flags.  See cp-tree.h for more info.  */
 
 tree
-build_delete (tree type, tree addr, special_function_kind auto_delete,
+build_delete (tree otype, tree addr, special_function_kind auto_delete,
              int flags, int use_global_delete, tsubst_flags_t complain)
 {
   tree expr;
@@ -3837,22 +3851,33 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
   if (addr == error_mark_node)
     return error_mark_node;
 
+  tree type = TYPE_MAIN_VARIANT (otype);
+
   /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type
      set to `error_mark_node' before it gets properly cleaned up.  */
   if (type == error_mark_node)
     return error_mark_node;
 
-  type = TYPE_MAIN_VARIANT (type);
+  if (TREE_CODE (type) == POINTER_TYPE)
+    type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
 
-  addr = mark_rvalue_use (addr);
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    {
+      if (TYPE_DOMAIN (type) == NULL_TREE)
+       {
+         if (complain & tf_error)
+           error ("unknown array size in delete");
+         return error_mark_node;
+       }
+      return build_vec_delete (addr, array_type_nelts (type),
+                              auto_delete, use_global_delete, complain);
+    }
 
-  if (TYPE_PTR_P (type))
+  if (TYPE_PTR_P (otype))
     {
       bool complete_p = true;
 
-      type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
-      if (TREE_CODE (type) == ARRAY_TYPE)
-       goto handle_array;
+      addr = mark_rvalue_use (addr);
 
       /* We don't want to warn about delete of void*, only other
          incomplete types.  Deleting other incomplete types
@@ -3908,19 +3933,6 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
       /* Throw away const and volatile on target type of addr.  */
       addr = convert_force (build_pointer_type (type), addr, 0, complain);
     }
-  else if (TREE_CODE (type) == ARRAY_TYPE)
-    {
-    handle_array:
-
-      if (TYPE_DOMAIN (type) == NULL_TREE)
-       {
-         if (complain & tf_error)
-           error ("unknown array size in delete");
-         return error_mark_node;
-       }
-      return build_vec_delete (addr, array_type_nelts (type),
-                              auto_delete, use_global_delete, complain);
-    }
   else
     {
       /* Don't check PROTECT here; leave that decision to the
@@ -3935,10 +3947,18 @@ build_delete (tree type, tree addr, special_function_kind auto_delete,
       addr = convert_force (build_pointer_type (type), addr, 0, complain);
     }
 
-  gcc_assert (MAYBE_CLASS_TYPE_P (type));
-
   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
     {
+      /* Make sure the destructor is callable.  */
+      if (type_build_dtor_call (type))
+       {
+         expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL,
+                                                        complain),
+                                 sfk_complete_destructor, flags, complain);
+         if (expr == error_mark_node)
+           return error_mark_node;
+       }
+
       if (auto_delete != sfk_deleting_destructor)
        return void_zero_node;
 
@@ -4062,7 +4082,7 @@ push_base_cleanups (void)
       for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
           vec_safe_iterate (vbases, i, &base_binfo); i++)
        {
-         if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
+         if (type_build_dtor_call (BINFO_TYPE (base_binfo)))
            {
              expr = build_special_member_call (current_class_ref,
                                                base_dtor_identifier,
@@ -4070,10 +4090,13 @@ push_base_cleanups (void)
                                                base_binfo,
                                                (LOOKUP_NORMAL
                                                 | LOOKUP_NONVIRTUAL),
-                                                tf_warning_or_error);
-             expr = build3 (COND_EXPR, void_type_node, cond,
-                            expr, void_zero_node);
-             finish_decl_cleanup (NULL_TREE, expr);
+                                               tf_warning_or_error);
+             if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
+               {
+                 expr = build3 (COND_EXPR, void_type_node, cond,
+                                expr, void_zero_node);
+                 finish_decl_cleanup (NULL_TREE, expr);
+               }
            }
        }
     }
@@ -4082,8 +4105,8 @@ push_base_cleanups (void)
   for (binfo = TYPE_BINFO (current_class_type), i = 0;
        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
     {
-      if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))
-         || BINFO_VIRTUAL_P (base_binfo))
+      if (BINFO_VIRTUAL_P (base_binfo)
+         || !type_build_dtor_call (BINFO_TYPE (base_binfo)))
        continue;
 
       expr = build_special_member_call (current_class_ref,
@@ -4091,7 +4114,8 @@ push_base_cleanups (void)
                                        NULL, base_binfo,
                                        LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
                                         tf_warning_or_error);
-      finish_decl_cleanup (NULL_TREE, expr);
+      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
+       finish_decl_cleanup (NULL_TREE, expr);
     }
 
   /* Don't automatically destroy union members.  */
@@ -4108,7 +4132,7 @@ push_base_cleanups (void)
        continue;
       if (ANON_UNION_TYPE_P (this_type))
        continue;
-      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (this_type))
+      if (type_build_dtor_call (this_type))
        {
          tree this_member = (build_class_member_access_expr
                              (current_class_ref, member,
@@ -4119,7 +4143,8 @@ push_base_cleanups (void)
                               sfk_complete_destructor,
                               LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL,
                               0, tf_warning_or_error);
-         finish_decl_cleanup (NULL_TREE, expr);
+         if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (this_type))
+           finish_decl_cleanup (NULL_TREE, expr);
        }
     }
 }
index 4ac533eacf7237fae7b912884d579fc6c65219d6..593a4a653e962021109bae55e0e9e1f2897e9cdd 100644 (file)
@@ -1265,8 +1265,9 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
      class versions and other properties of the type.  But a subobject
      class can be trivially copyable and yet have overload resolution
      choose a template constructor for initialization, depending on
-     rvalueness and cv-quals.  So we can't exit early for copy/move
-     methods in C++0x.  The same considerations apply in C++98/03, but
+     rvalueness and cv-quals.  And furthermore, a member in a base might
+     be trivial but deleted or otherwise not callable.  So we can't exit
+     early in C++0x.  The same considerations apply in C++98/03, but
      there the definition of triviality does not consider overload
      resolution, so a constructor can be trivial even if it would otherwise
      call a non-trivial constructor.  */
@@ -1282,7 +1283,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
            inform (input_location, "defaulted default constructor does "
                    "not initialize any non-static data member");
        }
-      if (!diag)
+      if (!diag && cxx_dialect < cxx11)
        return;
     }
 
@@ -1323,7 +1324,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
 
       process_subob_fn (rval, spec_p, trivial_p, deleted_p,
                        constexpr_p, diag, basetype);
-      if (ctor_p && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (basetype))
+      if (ctor_p)
        {
          /* In a constructor we also need to check the subobject
             destructors for cleanup of partially constructed objects.  */
index e56052d4fda3c987a1b84242e9b41e1f6aa388be..052746c15b79460b0283139debd4709b3e552956 100644 (file)
@@ -2521,6 +2521,10 @@ finish_compound_literal (tree type, tree compound_literal,
       decl = pushdecl_top_level (decl);
       DECL_NAME (decl) = make_anon_name ();
       SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+      /* Make sure the destructor is callable.  */
+      tree clean = cxx_maybe_build_cleanup (decl, complain);
+      if (clean == error_mark_node)
+       return error_mark_node;
       return decl;
     }
   else
index 011406ca3ab66e6599c5192bf43c78cc6ce2db5a..4b71a76f4d28aa74f375aa6ad0209758a71ea015 100644 (file)
@@ -640,12 +640,13 @@ split_nonconstant_init_1 (tree dest, tree init)
              code = build_stmt (input_location, EXPR_STMT, code);
              code = maybe_cleanup_point_expr_void (code);
              add_stmt (code);
-             if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type))
+             if (type_build_dtor_call (inner_type))
                {
                  code = (build_special_member_call
                          (sub, complete_dtor_identifier, NULL, inner_type,
                           LOOKUP_NORMAL, tf_warning_or_error));
-                 finish_eh_cleanup (code);
+                 if (!TYPE_HAS_TRIVIAL_DESTRUCTOR (inner_type))
+                   finish_eh_cleanup (code);
                }
 
              num_split_elts++;
index 560363274c2ea38e813c14b66a6b817626a2e545..f7de07306258815b0b28e5690ce5fe09a9df57fa 100644 (file)
@@ -1,5 +1,6 @@
-// We allocate a cookie to help us run the destructor even if it's deleted.
-// { dg-options -std=c++11 }
+// We don't allocate a cookie to help us run the destructor if it's trivial,
+// even if it's deleted.
+// { dg-options "-std=c++11" }
 // { dg-do run }
 
 struct A
@@ -17,5 +18,5 @@ void *operator new[](__SIZE_TYPE__ t)
 int main()
 {
   A* ap = new A[5];
-  return ap == p;
+  return ap != p;
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted19a.C b/gcc/testsuite/g++.dg/cpp0x/defaulted19a.C
new file mode 100644 (file)
index 0000000..6d2a26a
--- /dev/null
@@ -0,0 +1,24 @@
+// We allocate a cookie to help us run the destructor if it's non-trivial,
+// even if it's deleted.
+// { dg-options "-std=c++0x" }
+// { dg-do run }
+
+struct B { ~B() {} };
+struct A
+{
+  B b;
+  ~A() = delete;
+};
+
+void *p = 0;
+void *operator new[](__SIZE_TYPE__ t)
+{
+  p = ::operator new (t);
+  return p;
+}
+
+int main()
+{
+  A* ap = new A[5];
+  return ap == p;
+}
index 8a8c87463305268092971aa30651dbc4ae263c26..3cef60050ac4d14a74c2ebb44411b3a2e6abf939 100644 (file)
@@ -62,7 +62,7 @@ int main()
 {
   F f;
   F f2(f);                     // { dg-error "use" }
-  B* b = new const B;          // { dg-error "uninitialized const" }
+  const B* b = new const B;            // { dg-error "uninitialized const" }
   U u;                         // { dg-error "deleted" }
 }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted46.C b/gcc/testsuite/g++.dg/cpp0x/defaulted46.C
new file mode 100644 (file)
index 0000000..d4562c9
--- /dev/null
@@ -0,0 +1,17 @@
+// { dg-require-effective-target c++11 }
+
+struct A
+{
+protected:
+  A() = default;
+  int i;
+};
+
+struct B: A {
+  B() = default;
+};
+
+int main()
+{
+  B();
+}
index 3b536e7ec0629299acb652b937d1feccb0705234..9f5841d17cfccc5f04bdcdd1330795d063d44924 100644 (file)
@@ -12,6 +12,6 @@ struct B: A { };              // { dg-error "deleted" }
 extern B eb;
 int main()
 {
-  B* b1 = new B;               // { dg-error "use of deleted function" "" { xfail *-*-* } }
+  B* b1 = new B;               // { dg-error "use of deleted function" }
   B* b2 = new B(eb);           // { dg-error "use of deleted function" }
 }
index 3eab43cb0ac46c95933823a6948e50006870357d..62c003a458c4c298460904adef062066129be462 100644 (file)
@@ -9,6 +9,10 @@ char f(int);
 template<class>
 char (&f(...))[2];
 
-struct ND { ND() = delete; };
+struct ND {
+  // Make ND() non-aggregate.
+  virtual void f();
+  ND() = delete;
+};
 
 static_assert(sizeof(f<ND[1]>(0)) != 1, "Error");
index 5d0bf71ae636bba3ba37a58ba77d6e999de3b084..9c8e887daccec754025c3f44f744f68b29d26e41 100644 (file)
@@ -1,5 +1,5 @@
 // PR c++/14401
 
-struct { struct { int& i ; } bar ; } foo ; // { dg-error "uninitialized" "uninit" }
+struct { struct { int& i ; } bar ; } foo ; // { dg-error "deleted|uninitialized" "uninit" }
 // { dg-warning "anonymous" "anon" { target c++98 } 3 }
-// { dg-message "should be initialized" "ref-uninit" { target *-*-* } 3 }
+// { dg-message "should be initialized" "ref-uninit" { target c++98 } 3 }
index 3491f6a1d2cf07ab92ae25843e332b6388f92ec7..7eb72eb833fc348971b1919a9263230d15e5a2ad 100644 (file)
@@ -1,9 +1,10 @@
 // PR c++/29039
 
-typedef struct S {
+typedef struct S {         // { dg-error "reference" "" { target c++11 } }
   int &r; 
 }; // { dg-warning "'typedef' was ignored" }
 
+
 S f () {
-  return S (); // { dg-error "reference" }
+  return S (); // { dg-error "reference|deleted" }
 }
index c906a9bbd355ff9285faa312f1eb93d9d0c77c7e..e8945dafe933448fd89e08a11f94669328e9c12d 100644 (file)
@@ -1,51 +1,51 @@
 // PR c++/25811
 // { dg-do compile }
 
-struct A1
+struct A1              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const j; // { dg-message "should be initialized" }
+  int const j; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct A2
+struct A2              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const volatile i; // { dg-message "should be initialized" }
+  int const volatile i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct A3
+struct A3              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
+  int& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct A4
+struct A4              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const& ref; // { dg-message "should be initialized" }
+  int const& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct A5
+struct A5              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
-  int const i; // { dg-message "should be initialized" }
+  int& ref; // { dg-message "should be initialized" "" { target c++98 } }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-template <class T> struct S1
+template <class T> struct S1 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  T const i; // { dg-message "should be initialized" }
+  T const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-template <class T> struct S2
+template <class T> struct S2 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  T const volatile i; // { dg-message "should be initialized" }
+  T const volatile i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-template <class T> struct S3
+template <class T> struct S3 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  T& ref; // { dg-message "should be initialized" }
+  T& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-template <class T> struct S4
+template <class T> struct S4 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  T const i; // { dg-message "should be initialized" }
-  T& ref; // { dg-message "should be initialized" }
+  T const i; // { dg-message "should be initialized" "" { target c++98 } }
+  T& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
 struct X
@@ -55,44 +55,44 @@ struct X
   int const& r;
 };
 
-struct Y11
+struct Y11             // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const i; // { dg-message "should be initialized" }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct Y1
+struct Y1              // { dg-error "deleted" "" { target c++11 } }
 {
   Y11 a[1];
 };
 
-struct Y22
+struct Y22             // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
+  int& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct Y2
+struct Y2              // { dg-error "deleted" "" { target c++11 } }
 {
   Y22 a[1];
 };
 
-struct Z1
+struct Z1              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const i; // { dg-message "should be initialized" }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct Z2
+struct Z2 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
+  int& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct Z3
+struct Z3 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const i; // { dg-message "should be initialized" }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct Z4
+struct Z4 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
+  int& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
 struct Z5
@@ -100,7 +100,7 @@ struct Z5
   int i;
 };
 
-struct Z
+struct Z               // { dg-error "deleted" "" { target c++11 } }
 {
   Z1 z1;
   Z2 z2;
@@ -109,54 +109,54 @@ struct Z
   Z5 z5;
 };
 
-union U
+union U // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const i; // { dg-message "should be initialized" }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
 void f1 ()
 {
-  new A1; // { dg-error "uninitialized const member" }
+  new A1; // { dg-error "deleted|uninitialized const member" }
 }
 
 void f2 ()
 {
-  new A2; // { dg-error "uninitialized const member" }
+  new A2; // { dg-error "deleted|uninitialized const member" }
 }
 
 void f3 ()
 {
-  new A3; // { dg-error "uninitialized reference member" }
+  new A3; // { dg-error "deleted|uninitialized reference member" }
 }
 
 void f4 ()
 {
-  new A4; // { dg-error "uninitialized reference member" }
+  new A4; // { dg-error "deleted|uninitialized reference member" }
 }
 
 void f5 ()
 {
-  new A5; // { dg-error "uninitialized reference member|uninitialized const member" }
+  new A5; // { dg-error "deleted|uninitialized reference member|uninitialized const member" }
 }
 
 void f6 ()
 {
-  new S1<int>; // { dg-error "uninitialized const member" }
+  new S1<int>; // { dg-error "deleted|uninitialized const member" }
 }
 
 void f7 ()
 {
-  new S2<int>; // { dg-error "uninitialized const member" }
+  new S2<int>; // { dg-error "deleted|uninitialized const member" }
 }
 
 void f8 ()
 {
-  new S3<int>; // { dg-error "uninitialized reference member" }
+  new S3<int>; // { dg-error "deleted|uninitialized reference member" }
 }
 
 void f9 ()
 {
-  new S4<int>; // { dg-error "uninitialized reference member|uninitialized const member" }
+  new S4<int>; // { dg-error "deleted|uninitialized reference member|uninitialized const member" }
 }
 
 void f10 ()
@@ -166,30 +166,30 @@ void f10 ()
 
 void f11 ()
 {
-  new A1[1]; // { dg-error "uninitialized const member" }
+  new A1[1]; // { dg-error "deleted|uninitialized const member" }
 }
 
 void f12 ()
 {
-  new A3[1]; // { dg-error "uninitialized reference member" }
+  new A3[1]; // { dg-error "deleted|uninitialized reference member" }
 }
 
 void f13 ()
 {
-  new Y1; // { dg-error "uninitialized const member" }
+  new Y1; // { dg-error "deleted|uninitialized const member" }
 }
 
 void f14 ()
 {
-  new Y2; // { dg-error "uninitialized reference member" }
+  new Y2; // { dg-error "deleted|uninitialized reference member" }
 }
 
 void f15 ()
 {
-  new Z; // { dg-error "uninitialized reference member|uninitialized const member" }
+  new Z; // { dg-error "deleted|uninitialized reference member|uninitialized const member" }
 }
 
 void f16 ()
 {
-  new U; // { dg-error "uninitialized const member" }
+  new U; // { dg-error "deleted|uninitialized const member" }
 }
index 6ed31b5d6b503025944f35764596e553f3eb51d0..f868dfb91a4835724658a9e7417b59024149e04a 100644 (file)
@@ -1,27 +1,27 @@
 // PR c++/29043
 // { dg-do compile }
 
-struct S 
+struct S               // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const i; // { dg-message "should be initialized" }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
 class C
 {
 public:
-  C() {} // { dg-error "uninitialized const member" }   
+  C() {} // { dg-error "uninitialized const member|deleted" }
   S s;
 };
 
-struct S2
+struct S2              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
+  int& ref;   // { dg-message "should be initialized" "" { target c++98 } }
 };
 
 class C2
 {
 public:
-  C2() {} // { dg-error "uninitialized reference member" }   
+  C2() {} // { dg-error "uninitialized reference member|deleted" }
   S2 s;
 };
 
@@ -33,14 +33,14 @@ class C3
   };
 };
 
-struct S4
+struct S4              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const i; // { dg-message "should be initialized" }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
 struct C4
 {
-  C4() {} // { dg-error "uninitialized const member" }
+  C4() {} // { dg-error "uninitialized const member|deleted" }
   S4 s4[ 1 ];
 };
 
index d3487c94a0929c95c5108b989aed4589490e7d5f..13a82210bc611efc9679e4aaef8856cb182b87d6 100644 (file)
@@ -1,51 +1,51 @@
 // PR c++/43719
 // { dg-do compile }
 
-struct A1
+struct A1                // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const j; // { dg-message "should be initialized" }
+  int const j; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct A2
+struct A2                // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const volatile i; // { dg-message "should be initialized" }
+  int const volatile i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct A3
+struct A3                // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
+  int& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct A4
+struct A4                // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const& ref; // { dg-message "should be initialized" }
+  int const& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct A5
+struct A5                // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
-  int const i; // { dg-message "should be initialized" }
+  int& ref; // { dg-message "should be initialized" "" { target c++98 } }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-template <class T> struct S1
+template <class T> struct S1 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  T const i; // { dg-message "should be initialized" }
+  T const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-template <class T> struct S2
+template <class T> struct S2 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  T const volatile i; // { dg-message "should be initialized" }
+  T const volatile i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-template <class T> struct S3
+template <class T> struct S3 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  T& ref; // { dg-message "should be initialized" }
+  T& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-template <class T> struct S4
+template <class T> struct S4 // { dg-error "uninitialized" "" { target c++11 } }
 {
-  T const i; // { dg-message "should be initialized" }
-  T& ref; // { dg-message "should be initialized" }
+  T const i; // { dg-message "should be initialized" "" { target c++98 } }
+  T& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
 struct X
@@ -55,44 +55,44 @@ struct X
   int const& r;
 };
 
-struct Y11
+struct Y11               // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const i; // { dg-message "should be initialized" }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct Y1
+struct Y1                // { dg-error "deleted" "" { target c++11 } }
 {
   Y11 a[1];
 };
 
-struct Y22
+struct Y22            // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
+  int& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct Y2
+struct Y2                    // { dg-error "deleted" "" { target c++11 } }
 {
   Y22 a[1];
 };
 
-struct Z1
+struct Z1              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const i; // { dg-message "should be initialized" }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct Z2
+struct Z2              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
+  int& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct Z3
+struct Z3              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const i; // { dg-message "should be initialized" }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
-struct Z4
+struct Z4              // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int& ref; // { dg-message "should be initialized" }
+  int& ref; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
 struct Z5
@@ -100,7 +100,7 @@ struct Z5
   int i;
 };
 
-struct Z
+struct Z               // { dg-error "deleted" "" { target c++11 } }
 {
   Z1 z1;
   Z2 z2;
@@ -109,55 +109,55 @@ struct Z
   Z5 z5;
 };
 
-union U
+union U                        // { dg-error "uninitialized" "" { target c++11 } }
 {
-  int const i; // { dg-message "should be initialized" }
+  int const i; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
 
 void f1 ()
 {
-  A1 a1; // { dg-error "uninitialized const member" }
+  A1 a1; // { dg-error "uninitialized const member|deleted" }
 }
 
 void f2 ()
 {
-  A2 a2; // { dg-error "uninitialized const member" }
+  A2 a2; // { dg-error "uninitialized const member|deleted" }
 }
 
 void f3 ()
 {
-  A3 a3; // { dg-error "uninitialized reference member" }
+  A3 a3; // { dg-error "uninitialized reference member|deleted" }
 }
 
 void f4 ()
 {
-  A4 a4; // { dg-error "uninitialized reference member" }
+  A4 a4; // { dg-error "uninitialized reference member|deleted" }
 }
 
 void f5 ()
 {
-  A5 a5; // { dg-error "uninitialized reference member|uninitialized const member" }
+  A5 a5; // { dg-error "uninitialized reference member|uninitialized const member|deleted" }
 }
 
 void f6 ()
 {
-  S1<int> s; // { dg-error "uninitialized const member" }
+  S1<int> s; // { dg-error "uninitialized const member|deleted" }
 }
 
 void f7 ()
 {
-  S2<int> s; // { dg-error "uninitialized const member" }
+  S2<int> s; // { dg-error "uninitialized const member|deleted" }
 }
 
 void f8 ()
 {
-  S3<int> s; // { dg-error "uninitialized reference member" }
+  S3<int> s; // { dg-error "uninitialized reference member|deleted" }
 }
 
 void f9 ()
 {
-  S4<int> s; // { dg-error "uninitialized reference member|uninitialized const member" }
+  S4<int> s; // { dg-error "uninitialized reference member|uninitialized const member|deleted" }
 }
 
 void f10 ()
@@ -167,31 +167,31 @@ void f10 ()
 
 void f11 ()
 {
-  A1 a[ 1 ]; // { dg-error "uninitialized const member" }
+  A1 a[ 1 ]; // { dg-error "uninitialized const member|deleted" }
 }
 
 void f12 ()
 {
-  A3 a[ 1 ]; // { dg-error "uninitialized reference member" }
+  A3 a[ 1 ]; // { dg-error "uninitialized reference member|deleted" }
 }
 
 void f13 ()
 {
-  Y1 y1; // { dg-error "uninitialized const member" }
+  Y1 y1; // { dg-error "uninitialized const member|deleted" }
 }
 
 void f14 ()
 {
-  Y2 y2; // { dg-error "uninitialized reference member" }
+  Y2 y2; // { dg-error "uninitialized reference member|deleted" }
 }
 
 void f15 ()
 {
-  Z z; // { dg-error "uninitialized reference member|uninitialized const member" }
+  Z z; // { dg-error "uninitialized reference member|uninitialized const member|deleted" }
 }
 
 void f16 ()
 {
-  U u; // { dg-error "uninitialized const member" }
+  U u; // { dg-error "uninitialized const member|deleted" }
 }
 
index e3304f4a27b38ceb034c9210ddbe1ce25bc88658..b4b0833dd69acd834c9d479e510bfe5586a6961b 100644 (file)
@@ -1,15 +1,15 @@
 // PR c++/44086
 // { dg-do compile }
 
-struct A
+struct A               // { dg-error "uninitialized" "" { target c++11 } }
 {
-    int const i : 2; // { dg-message "should be initialized" }
+    int const i : 2; // { dg-message "should be initialized" "" { target c++98 } }
 };
 
 void f()
 {
-    A a;    // { dg-error "uninitialized const" }
-    new A;  // { dg-error "uninitialized const" }
-    A();
-    new A();
+    A a;                     // { dg-error "deleted|uninitialized const" }
+    new A;                   // { dg-error "deleted|uninitialized const" }
+    A();                     // { dg-error "deleted" "" { target c++11 } }
+    new A();                 // { dg-error "deleted" "" { target c++11 } }
 }
index 212e6e95d7eab4152eb8ed9d949b21eb0b52a855..6ac42415b4376cab478f57f2c90247e44a3c2143 100644 (file)
@@ -1,4 +1,6 @@
 // PR c++/33459
+// { dg-prune-output "uninitialized" }
+// { dg-prune-output "deleted" }
 
 union A
 {
index 200c424305d682614f234a554561d7d3ce6ad2d3..1e4f7ae84e2eb1be5804a3a0d6a674db263903fb 100644 (file)
@@ -1,12 +1,12 @@
 // PR c++/58126
 
-struct A {
+struct A {             // { dg-error "uninitialized" "" { target c++11 } }
   const int value1;
   int& value2;
 };
 
-struct B : A { };
+struct B : A { };      // { dg-error "deleted" "" { target c++11 } }
 
-A a;  // { dg-error "uninitialized const member in 'struct A'|uninitialized reference member in 'struct A'" }
+A a;  // { dg-error "deleted|uninitialized const member in 'struct A'|uninitialized reference member in 'struct A'" }
 
-B b;  // { dg-error "uninitialized const member in base 'struct A' of 'struct B'|uninitialized reference member in base 'struct A' of 'struct B'" }
+B b;  // { dg-error "deleted|uninitialized const member in base 'struct A' of 'struct B'|uninitialized reference member in base 'struct A' of 'struct B'" }