Avoid calling a trivial default constructor.
authorJason Merrill <jason@redhat.com>
Fri, 26 Aug 2016 15:10:57 +0000 (11:10 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 26 Aug 2016 15:10:57 +0000 (11:10 -0400)
* class.c (default_ctor_p): New.
(in_class_defaulted_default_constructor): Use it.
(type_has_non_user_provided_default_constructor): Use it.
* call.c (build_over_call): Handle trivial default constructor.
* cp-tree.h: Declare default_ctor_p.

From-SVN: r239783

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/testsuite/g++.dg/cpp0x/explicit12.C

index 812c8c1..e8e2e03 100644 (file)
@@ -1,5 +1,12 @@
 2016-08-15  Jason Merrill  <jason@redhat.com>
 
+       Avoid calling a trivial default constructor.
+       * class.c (default_ctor_p): New.
+       (in_class_defaulted_default_constructor): Use it.
+       (type_has_non_user_provided_default_constructor): Use it.
+       * call.c (build_over_call): Handle trivial default constructor.
+       * cp-tree.h: Declare default_ctor_p.
+
        PR c++/57728
        * pt.c (do_type_instantiation): Don't mess with non-user-provided
        member functions.
index 05f0431..024519d 100644 (file)
@@ -7798,11 +7798,19 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
 
       return val;
     }
-  else if (DECL_DESTRUCTOR_P (fn)
-          && trivial_fn_p (fn)
-          && !DECL_DELETED_FN (fn))
-    return fold_convert (void_type_node, argarray[0]);
-  /* FIXME handle trivial default constructor, too.  */
+  else if (!DECL_DELETED_FN (fn)
+          && trivial_fn_p (fn))
+    {
+      if (DECL_DESTRUCTOR_P (fn))
+       return fold_convert (void_type_node, argarray[0]);
+      else if (default_ctor_p (fn))
+       {
+         if (is_dummy_object (argarray[0]))
+           return force_target_expr (DECL_CONTEXT (fn), void_node, complain);
+         else
+           return cp_build_indirect_ref (argarray[0], RO_NULL, complain);
+       }
+    }
 
   /* For calls to a multi-versioned function, overload resolution
      returns the function with the highest target priority, that is,
index 20689e4..a4f3c6b 100644 (file)
@@ -5133,8 +5133,17 @@ set_method_tm_attributes (tree t)
     }
 }
 
-/* Returns true iff class T has a user-defined constructor other than
-   the default constructor.  */
+/* Returns true if FN is a default constructor.  */
+
+bool
+default_ctor_p (tree fn)
+{
+  return (DECL_CONSTRUCTOR_P (fn)
+         && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)));
+}
+
+/* Returns true iff class T has a user-defined constructor that can be called
+   with more than zero arguments.  */
 
 bool
 type_has_user_nondefault_constructor (tree t)
@@ -5163,23 +5172,16 @@ type_has_user_nondefault_constructor (tree t)
 tree
 in_class_defaulted_default_constructor (tree t)
 {
-  tree fns, args;
-
   if (!TYPE_HAS_USER_CONSTRUCTOR (t))
     return NULL_TREE;
 
-  for (fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
+  for (tree fns = CLASSTYPE_CONSTRUCTORS (t); fns; fns = OVL_NEXT (fns))
     {
       tree fn = OVL_CURRENT (fns);
 
-      if (DECL_DEFAULTED_IN_CLASS_P (fn))
-       {
-         args = FUNCTION_FIRST_USER_PARMTYPE (fn);
-         while (args && TREE_PURPOSE (args))
-           args = TREE_CHAIN (args);
-         if (!args || args == void_list_node)
-           return fn;
-       }
+      if (DECL_DEFAULTED_IN_CLASS_P (fn)
+         && default_ctor_p (fn))
+       return fn;
     }
 
   return NULL_TREE;
@@ -5268,8 +5270,8 @@ type_has_non_user_provided_default_constructor (tree t)
     {
       tree fn = OVL_CURRENT (fns);
       if (TREE_CODE (fn) == FUNCTION_DECL
-         && !user_provided_p (fn)
-         && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)))
+         && default_ctor_p (fn)
+         && !user_provided_p (fn))
        return true;
     }
 
index 8a32f17..72a128d 100644 (file)
@@ -5666,6 +5666,7 @@ extern void determine_key_method          (tree);
 extern void check_for_override                 (tree, tree);
 extern void push_class_stack                   (void);
 extern void pop_class_stack                    (void);
+extern bool default_ctor_p                     (tree);
 extern bool type_has_user_nondefault_constructor (tree);
 extern tree in_class_defaulted_default_constructor (tree);
 extern bool user_provided_p                    (tree);
index 5c14c01..912d507 100644 (file)
@@ -15,3 +15,5 @@ int main()
 {
   A<int> a;
 }
+
+// { dg-final { scan-assembler-not "_ZN1AIiEC1Ev" } }