re PR c++/63362 (The c++11 triviality-traits need front-end help)
authorJason Merrill <jason@redhat.com>
Wed, 1 Oct 2014 17:21:01 +0000 (13:21 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 1 Oct 2014 17:21:01 +0000 (13:21 -0400)
PR c++/63362
* class.c (type_has_non_user_provided_default_constructor): Rename
from type_has_user_provided_default_constructor, reverse sense.
(default_init_uninitialized_part, explain_non_literal_class): Adjust.
(check_bases_and_members): Set TYPE_HAS_COMPLEX_DFLT.
* call.c (build_new_method_call_1): Adjust.
* cp-tree.h: Adjust.
* decl.c (grok_special_member_properties): Don't set
TYPE_HAS_COMPLEX_DFLT.
* init.c (build_value_init_noctor): Don't use
type_has_user_provided_default_constructor.

From-SVN: r215771

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/decl.c
gcc/cp/init.c
gcc/testsuite/g++.dg/ext/is_trivially_constructible2.C [new file with mode: 0644]

index 2fedd372a48fb1605ec46c50defdd6917cffabbf..9a9fc34256945f775f4ff46fc0ad48cdfd5b8b25 100644 (file)
@@ -1,3 +1,17 @@
+2014-10-01  Jason Merrill  <jason@redhat.com>
+
+       PR c++/63362
+       * class.c (type_has_non_user_provided_default_constructor): Rename
+       from type_has_user_provided_default_constructor, reverse sense.
+       (default_init_uninitialized_part, explain_non_literal_class): Adjust.
+       (check_bases_and_members): Set TYPE_HAS_COMPLEX_DFLT.
+       * call.c (build_new_method_call_1): Adjust.
+       * cp-tree.h: Adjust.
+       * decl.c (grok_special_member_properties): Don't set
+       TYPE_HAS_COMPLEX_DFLT.
+       * init.c (build_value_init_noctor): Don't use
+       type_has_user_provided_default_constructor.
+
 2014-09-30  Jason Merrill  <jason@redhat.com>
 
        * cp-tree.h (cp_trait_kind): Add CPTK_IS_TRIVIALLY_ASSIGNABLE and
index 8f1b91a4f169272d8253289ba57726b4d22d6635..3c8b338382abdfc7bfcd3ed05be060fb7961150d 100644 (file)
@@ -7941,7 +7941,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
          && TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)
          /* For a user-provided default constructor, use the normal
             mechanisms so that protected access works.  */
-         && !type_has_user_provided_default_constructor (basetype)
+         && type_has_non_user_provided_default_constructor (basetype)
          && !processing_template_decl)
        init = build_value_init (basetype, complain);
 
index acf5768b7d311542573e001636ab0bd77bb3828b..12ac30a84a84ac09bf75acd6612097e22b839025 100644 (file)
@@ -4937,21 +4937,25 @@ type_has_user_provided_constructor (tree t)
   return false;
 }
 
-/* Returns true iff class T has a user-provided default constructor.  */
+/* Returns true iff class T has a non-user-provided (i.e. implicitly
+   declared or explicitly defaulted in the class body) default
+   constructor.  */
 
 bool
-type_has_user_provided_default_constructor (tree t)
+type_has_non_user_provided_default_constructor (tree t)
 {
   tree fns;
 
-  if (!TYPE_HAS_USER_CONSTRUCTOR (t))
+  if (!TYPE_HAS_DEFAULT_CONSTRUCTOR (t))
     return false;
+  if (CLASSTYPE_LAZY_DEFAULT_CTOR (t))
+    return true;
 
   for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
     {
       tree fn = OVL_CURRENT (fns);
       if (TREE_CODE (fn) == FUNCTION_DECL
-         && user_provided_p (fn)
+         && !user_provided_p (fn)
          && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)))
        return true;
     }
@@ -5009,7 +5013,7 @@ default_init_uninitialized_part (tree type)
   type = strip_array_types (type);
   if (!CLASS_TYPE_P (type))
     return type;
-  if (type_has_user_provided_default_constructor (type))
+  if (!type_has_non_user_provided_default_constructor (type))
     return NULL_TREE;
   for (binfo = TYPE_BINFO (type), i = 0;
        BINFO_BASE_ITERATE (binfo, i, t); ++i)
@@ -5383,8 +5387,7 @@ explain_non_literal_class (tree t)
       inform (0, "  %q+T is not an aggregate, does not have a trivial "
              "default constructor, and has no constexpr constructor that "
              "is not a copy or move constructor", t);
-      if (TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
-         && !type_has_user_provided_default_constructor (t))
+      if (type_has_non_user_provided_default_constructor (t))
        {
          /* Note that we can't simply call locate_ctor because when the
             constructor is deleted it just returns NULL_TREE.  */
@@ -5528,6 +5531,13 @@ check_bases_and_members (tree t)
   TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) |= TYPE_CONTAINS_VPTR_P (t);
   TYPE_HAS_COMPLEX_DFLT (t) |= TYPE_CONTAINS_VPTR_P (t);
 
+  /* If the only explicitly declared default constructor is user-provided,
+     set TYPE_HAS_COMPLEX_DFLT.  */
+  if (!TYPE_HAS_COMPLEX_DFLT (t)
+      && TYPE_HAS_DEFAULT_CONSTRUCTOR (t)
+      && !type_has_non_user_provided_default_constructor (t))
+    TYPE_HAS_COMPLEX_DFLT (t) = true;
+
   /* Warn if a public base of a polymorphic type has an accessible
      non-virtual destructor.  It is only now that we know the class is
      polymorphic.  Although a polymorphic base will have a already
index b2b9063a3655605bdaa8aeb4f12bcd402151c115..14ec837dc9c267122ae13fd6c0c9dce55ec402d0 100644 (file)
@@ -3484,7 +3484,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 /* Nonzero if there is a non-trivial X::X(X&&) for this class.  */
 #define TYPE_HAS_COMPLEX_MOVE_CTOR(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_move_ctor)
 
-/* Nonzero if there is a non-trivial default constructor for this class.  */
+/* Nonzero if there is no trivial default constructor for this class.  */
 #define TYPE_HAS_COMPLEX_DFLT(NODE) (LANG_TYPE_CLASS_CHECK (NODE)->has_complex_dflt)
 
 /* Nonzero if TYPE has a trivial destructor.  From [class.dtor]:
@@ -5195,7 +5195,7 @@ extern bool type_has_user_nondefault_constructor (tree);
 extern tree in_class_defaulted_default_constructor (tree);
 extern bool user_provided_p                    (tree);
 extern bool type_has_user_provided_constructor  (tree);
-extern bool type_has_user_provided_default_constructor (tree);
+extern bool type_has_non_user_provided_default_constructor (tree);
 extern bool vbase_has_user_provided_move_assign (tree);
 extern tree default_init_uninitialized_part (tree);
 extern bool trivial_default_constructor_is_constexpr (tree);
index d26a432bf6e1f41e7ddb1ee65ec86e771268e92d..7856dd836edb88ffc62bc1ccf83d75dcf70927ec 100644 (file)
@@ -11476,11 +11476,7 @@ grok_special_member_properties (tree decl)
            TYPE_HAS_CONST_COPY_CTOR (class_type) = 1;
        }
       else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
-       {
-         TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
-         if (user_provided_p (decl))
-           TYPE_HAS_COMPLEX_DFLT (class_type) = 1;
-       }
+       TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
       else if (move_fn_p (decl) && user_provided_p (decl))
        TYPE_HAS_COMPLEX_MOVE_CTOR (class_type) = 1;
       else if (is_list_ctor (decl))
index f0ca9b9a396c5faa0924ff050dfa828115e61895..6851fe9dc7e7d1da79b05c68bfe16e9a6eb2e0ad 100644 (file)
@@ -343,13 +343,17 @@ build_value_init (tree type, tsubst_flags_t complain)
   if (CLASS_TYPE_P (type)
       && type_build_ctor_call (type))
     {
-      tree ctor = build_aggr_init_expr
-       (type,
+      tree ctor =
         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))
+                                   complain);
+      if (ctor == error_mark_node)
+       return ctor;
+      tree fn = NULL_TREE;
+      if (TREE_CODE (ctor) == CALL_EXPR)
+       fn = get_callee_fndecl (ctor);
+      ctor = build_aggr_init_expr (type, ctor);
+      if (fn && user_provided_p (fn))
        return ctor;
       else if (TYPE_HAS_COMPLEX_DFLT (type))
        {
diff --git a/gcc/testsuite/g++.dg/ext/is_trivially_constructible2.C b/gcc/testsuite/g++.dg/ext/is_trivially_constructible2.C
new file mode 100644 (file)
index 0000000..4e0a657
--- /dev/null
@@ -0,0 +1,15 @@
+// { dg-do compile { target c++11 } }
+
+struct X {
+  X() = default;
+  template<class... U> X(U...);
+};
+
+struct Y {
+  template<class... U> Y(U...);
+};
+
+#define SA(X) static_assert((X),#X)
+
+SA(__is_trivially_constructible(X));
+SA(!__is_trivially_constructible(Y));