Class template argument deduction in new-expression
[gcc.git] / gcc / cp / init.c
index 63c3dab9b643ccff287c11331e476db1ca3d46f7..191fe13e31039947d1d5d660eef0b9c0d8d9ba94 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle initialization things in C++.
-   Copyright (C) 1987-2016 Free Software Foundation, Inc.
+   Copyright (C) 1987-2017 Free Software Foundation, Inc.
    Contributed by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GCC.
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "varasm.h"
 #include "gimplify.h"
 #include "c-family/c-ubsan.h"
+#include "intl.h"
 
 static bool begin_init_stmts (tree *, tree *);
 static tree finish_init_stmts (bool, tree, tree);
@@ -597,6 +598,34 @@ get_nsdmi (tree member, bool in_ctor)
   return init;
 }
 
+/* Diagnose the flexible array MEMBER if its INITializer is non-null
+   and return true if so.  Otherwise return false.  */
+
+bool
+maybe_reject_flexarray_init (tree member, tree init)
+{
+  tree type = TREE_TYPE (member);
+
+  if (!init
+      || TREE_CODE (type) != ARRAY_TYPE
+      || TYPE_DOMAIN (type))
+    return false;
+
+  /* Point at the flexible array member declaration if it's initialized
+     in-class, and at the ctor if it's initialized in a ctor member
+     initializer list.  */
+  location_t loc;
+  if (DECL_INITIAL (member) == init
+      || !current_function_decl
+      || DECL_DEFAULTED_FN (current_function_decl))
+    loc = DECL_SOURCE_LOCATION (member);
+  else
+    loc = DECL_SOURCE_LOCATION (current_function_decl);
+
+  error_at (loc, "initializer for flexible array member %q#D", member);
+  return true;
+}
+
 /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
    arguments.  If TREE_LIST is void_type_node, an empty initializer
    list was given; if NULL_TREE no initializer was given.  */
@@ -722,10 +751,18 @@ perform_member_init (tree member, tree init)
        {
          if (init)
            {
-             if (TREE_CHAIN (init))
+             /* Check to make sure the member initializer is valid and
+                something like a CONSTRUCTOR in: T a[] = { 1, 2 } and
+                if it isn't, return early to avoid triggering another
+                error below.  */
+             if (maybe_reject_flexarray_init (member, init))
+               return;
+
+             if (TREE_CODE (init) != TREE_LIST || TREE_CHAIN (init))
                init = error_mark_node;
              else
                init = TREE_VALUE (init);
+
              if (BRACE_ENCLOSED_INITIALIZER_P (init))
                init = digest_init (type, init, tf_warning_or_error);
            }
@@ -801,7 +838,8 @@ perform_member_init (tree member, tree init)
        init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
                                                tf_warning_or_error);
 
-      if (init)
+      /* Reject a member initializer for a flexible array member.  */
+      if (init && !maybe_reject_flexarray_init (member, init))
        finish_expr_stmt (cp_build_modify_expr (input_location, decl,
                                                INIT_EXPR, init,
                                                tf_warning_or_error));
@@ -1117,7 +1155,7 @@ emit_mem_initializers (tree mem_inits)
     }
 
   if (DECL_DEFAULTED_FN (current_function_decl)
-      && ! DECL_INHERITED_CTOR_BASE (current_function_decl))
+      && ! DECL_INHERITED_CTOR (current_function_decl))
     flags |= LOOKUP_DEFAULTED;
 
   /* Sort the mem-initializers into the order in which the
@@ -1138,6 +1176,13 @@ emit_mem_initializers (tree mem_inits)
       if (arguments == error_mark_node)
        continue;
 
+      /* Suppress access control when calling the inherited ctor.  */
+      bool inherited_base = (DECL_INHERITED_CTOR (current_function_decl)
+                            && flag_new_inheriting_ctors
+                            && arguments);
+      if (inherited_base)
+       push_deferring_access_checks (dk_deferred);
+
       if (arguments == NULL_TREE)
        {
          /* If these initializations are taking place in a copy constructor,
@@ -1154,9 +1199,7 @@ emit_mem_initializers (tree mem_inits)
        }
 
       /* Initialize the base.  */
-      if (BINFO_VIRTUAL_P (subobject))
-       construct_virtual_base (subobject, arguments);
-      else
+      if (!BINFO_VIRTUAL_P (subobject))
        {
          tree base_addr;
 
@@ -1170,6 +1213,19 @@ emit_mem_initializers (tree mem_inits)
                               tf_warning_or_error);
          expand_cleanup_for_base (subobject, NULL_TREE);
        }
+      else if (!ABSTRACT_CLASS_TYPE_P (current_class_type))
+       /* C++14 DR1658 Means we do not have to construct vbases of
+          abstract classes.  */
+       construct_virtual_base (subobject, arguments);
+      else
+       /* When not constructing vbases of abstract classes, at least mark
+          the arguments expressions as read to avoid
+          -Wunused-but-set-parameter false positives.  */
+       for (tree arg = arguments; arg; arg = TREE_CHAIN (arg))
+         mark_exp_read (TREE_VALUE (arg));
+
+      if (inherited_base)
+       pop_deferring_access_checks ();
     }
   in_base_initializer = 0;
 
@@ -1554,36 +1610,47 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
   TREE_READONLY (exp) = 0;
   TREE_THIS_VOLATILE (exp) = 0;
 
-  if (init && init != void_type_node
-      && TREE_CODE (init) != TREE_LIST
-      && !(TREE_CODE (init) == TARGET_EXPR
-          && TARGET_EXPR_DIRECT_INIT_P (init))
-      && !DIRECT_LIST_INIT_P (init))
-    flags |= LOOKUP_ONLYCONVERTING;
-
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
-      tree itype;
+      tree itype = init ? TREE_TYPE (init) : NULL_TREE;
+      int from_array = 0;
 
-      /* An array may not be initialized use the parenthesized
-        initialization form -- unless the initializer is "()".  */
-      if (init && TREE_CODE (init) == TREE_LIST)
+      if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp))
        {
-          if (complain & tf_error)
-            error ("bad array initializer");
-         return error_mark_node;
+         from_array = 1;
+         if (init && DECL_P (init)
+             && !(flags & LOOKUP_ONLYCONVERTING))
+           {
+             /* Wrap the initializer in a CONSTRUCTOR so that build_vec_init
+                recognizes it as direct-initialization.  */
+             init = build_constructor_single (init_list_type_node,
+                                              NULL_TREE, init);
+             CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
+           }
+       }
+      else
+       {
+         /* An array may not be initialized use the parenthesized
+            initialization form -- unless the initializer is "()".  */
+         if (init && TREE_CODE (init) == TREE_LIST)
+           {
+             if (complain & tf_error)
+               error ("bad array initializer");
+             return error_mark_node;
+           }
+         /* Must arrange to initialize each element of EXP
+            from elements of INIT.  */
+         if (cv_qualified_p (type))
+           TREE_TYPE (exp) = cv_unqualified (type);
+         if (itype && cv_qualified_p (itype))
+           TREE_TYPE (init) = cv_unqualified (itype);
+         from_array = (itype && same_type_p (TREE_TYPE (init),
+                                             TREE_TYPE (exp)));
        }
-      /* Must arrange to initialize each element of EXP
-        from elements of INIT.  */
-      itype = init ? TREE_TYPE (init) : NULL_TREE;
-      if (cv_qualified_p (type))
-       TREE_TYPE (exp) = cv_unqualified (type);
-      if (itype && cv_qualified_p (itype))
-       TREE_TYPE (init) = cv_unqualified (itype);
+
       stmt_expr = build_vec_init (exp, NULL_TREE, init,
                                  /*explicit_value_init_p=*/false,
-                                 itype && same_type_p (TREE_TYPE (init),
-                                                       TREE_TYPE (exp)),
+                                 from_array,
                                   complain);
       TREE_READONLY (exp) = was_const;
       TREE_THIS_VOLATILE (exp) = was_volatile;
@@ -1594,6 +1661,13 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
       return stmt_expr;
     }
 
+  if (init && init != void_type_node
+      && TREE_CODE (init) != TREE_LIST
+      && !(TREE_CODE (init) == TARGET_EXPR
+          && TARGET_EXPR_DIRECT_INIT_P (init))
+      && !DIRECT_LIST_INIT_P (init))
+    flags |= LOOKUP_ONLYCONVERTING;
+
   if ((VAR_P (exp) || TREE_CODE (exp) == PARM_DECL)
       && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (type)))
     /* Just know that we've seen something for this node.  */
@@ -1642,13 +1716,6 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
        init = reshape_init (type, init, complain);
     }
 
-  /* Also pull out a TARGET_EXPR that we want to avoid copying.  */
-  if (init && true_exp == exp
-      && TREE_CODE (init) == TREE_LIST
-      && list_length (init) == 1
-      && early_elide_copy (type, TREE_VALUE (init)))
-    init = TREE_VALUE (init);
-
   if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
       && CP_AGGREGATE_TYPE_P (type))
     /* A brace-enclosed initializer for an aggregate.  In C++0x this can
@@ -1659,12 +1726,14 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
      initializer, whether that happened just above or in
      cp_parser_late_parsing_nsdmi.
 
-     A TARGET_EXPR for which early_elide_copy is true represents the whole
-     initialization, so we shouldn't build up another ctor call.  */
-
+     A TARGET_EXPR with TARGET_EXPR_DIRECT_INIT_P or TARGET_EXPR_LIST_INIT_P
+     set represents the whole initialization, so we shouldn't build up
+     another ctor call.  */
   if (init
       && (TREE_CODE (init) == CONSTRUCTOR
-         || early_elide_copy (type, init))
+         || (TREE_CODE (init) == TARGET_EXPR
+             && (TARGET_EXPR_DIRECT_INIT_P (init)
+                 || TARGET_EXPR_LIST_INIT_P (init))))
       && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init), type))
     {
       /* Early initialization via a TARGET_EXPR only works for
@@ -1980,14 +2049,16 @@ build_offset_ref (tree type, tree member, bool address_p,
               If the access is to form a pointer to member, the
               nested-name-specifier shall name the derived class
               (or any class derived from that class).  */
+         bool ok;
          if (address_p && DECL_P (t)
              && DECL_NONSTATIC_MEMBER_P (t))
-           perform_or_defer_access_check (TYPE_BINFO (type), t, t,
-                                          complain);
+           ok = perform_or_defer_access_check (TYPE_BINFO (type), t, t,
+                                               complain);
          else
-           perform_or_defer_access_check (basebinfo, t, t,
-                                          complain);
-
+           ok = perform_or_defer_access_check (basebinfo, t, t,
+                                               complain);
+         if (!ok)
+           return error_mark_node;
          if (DECL_STATIC_FUNCTION_P (t))
            return t;
          member = t;
@@ -1996,11 +2067,14 @@ build_offset_ref (tree type, tree member, bool address_p,
        TREE_TYPE (member) = unknown_type_node;
     }
   else if (address_p && TREE_CODE (member) == FIELD_DECL)
-    /* We need additional test besides the one in
-       check_accessibility_of_qualified_id in case it is
-       a pointer to non-static member.  */
-    perform_or_defer_access_check (TYPE_BINFO (type), member, member,
-                                  complain);
+    {
+      /* We need additional test besides the one in
+        check_accessibility_of_qualified_id in case it is
+        a pointer to non-static member.  */
+      if (!perform_or_defer_access_check (TYPE_BINFO (type), member, member,
+                                         complain))
+       return error_mark_node;
+    }
 
   if (!address_p)
     {
@@ -2064,10 +2138,9 @@ static tree
 constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p)
 {
   while (TREE_CODE (decl) == CONST_DECL
-        || (strict_p
-            ? decl_constant_var_p (decl)
-            : (VAR_P (decl)
-               && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))))
+        || decl_constant_var_p (decl)
+        || (!strict_p && VAR_P (decl)
+            && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))))
     {
       tree init;
       /* If DECL is a static data member in a template
@@ -2365,7 +2438,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
      to placement new is not checked since it's unknown what it might
      point to.  */
   if (TREE_CODE (oper) == PARM_DECL
-      || TREE_CODE (oper) == VAR_DECL
+      || VAR_P (oper)
       || TREE_CODE (oper) == COMPONENT_REF)
     return;
 
@@ -2438,13 +2511,13 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
     {
       tree op0 = oper;
       while (TREE_CODE (op0 = TREE_OPERAND (op0, 0)) == COMPONENT_REF);
-      if (TREE_CODE (op0) == VAR_DECL)
+      if (VAR_P (op0))
        var_decl = op0;
       oper = TREE_OPERAND (oper, 1);
     }
 
   if ((addr_expr || !POINTER_TYPE_P (TREE_TYPE (oper)))
-      && (TREE_CODE (oper) == VAR_DECL
+      && (VAR_P (oper)
          || TREE_CODE (oper) == FIELD_DECL
          || TREE_CODE (oper) == PARM_DECL))
     {
@@ -2458,7 +2531,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
       /* Treat members of unions and members of structs uniformly, even
         though the size of a member of a union may be viewed as extending
         to the end of the union itself (it is by __builtin_object_size).  */
-      if ((TREE_CODE (oper) == VAR_DECL || use_obj_size)
+      if ((VAR_P (oper) || use_obj_size)
          && DECL_SIZE_UNIT (oper)
          && tree_fits_uhwi_p (DECL_SIZE_UNIT (oper)))
        {
@@ -2574,7 +2647,7 @@ warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
                        exact_size ?
                        "placement new constructing an object of type %qT "
                        "and size %qwu in a region of type %qT and size %qwi"
-                       : "placement new constructing an object of type %qT"
+                       : "placement new constructing an object of type %qT "
                        "and size %qwu in a region of type %qT and size "
                        "at most %qwu",
                        type, bytes_need, TREE_TYPE (oper),
@@ -2592,6 +2665,16 @@ type_has_new_extended_alignment (tree t)
          && TYPE_ALIGN_UNIT (t) > (unsigned)aligned_new_threshold);
 }
 
+/* Return the alignment we expect malloc to guarantee.  This should just be
+   MALLOC_ABI_ALIGNMENT, but that macro defaults to only BITS_PER_WORD for some
+   reason, so don't let the threshold be smaller than max_align_t_align.  */
+
+unsigned
+malloc_alignment ()
+{
+  return MAX (max_align_t_align(), MALLOC_ABI_ALIGNMENT);
+}
+
 /* Generate code for a new-expression, including calling the "operator
    new" function, initializing the object, and, if an exception occurs
    during construction, cleaning up.  The arguments are as for
@@ -2732,15 +2815,12 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
     {
       if (complain & tf_warning_or_error)
        {
-         const char *msg;
-         if (typedef_variant_p (orig_type))
-           msg = ("non-constant array new length must be specified "
-                  "directly, not by typedef");
-         else
-           msg = ("non-constant array new length must be specified "
-                  "without parentheses around the type-id");
-         pedwarn (EXPR_LOC_OR_LOC (outer_nelts, input_location),
-                  OPT_Wvla, msg);
+         pedwarn (EXPR_LOC_OR_LOC (outer_nelts, input_location), OPT_Wvla,
+                  typedef_variant_p (orig_type)
+                  ? G_("non-constant array new length must be specified "
+                       "directly, not by typedef")
+                  : G_("non-constant array new length must be specified "
+                       "without parentheses around the type-id"));
        }
       else
        return error_mark_node;
@@ -2882,7 +2962,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
   tree fnname;
   tree fns;
 
-  fnname = ansi_opname (array_p ? VEC_NEW_EXPR : NEW_EXPR);
+  fnname = cp_operator_id (array_p ? VEC_NEW_EXPR : NEW_EXPR);
 
   member_new_p = !globally_qualified_p
                 && CLASS_TYPE_P (elt_type)
@@ -2977,8 +3057,23 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
 
   gcc_assert (alloc_fn != NULL_TREE);
 
+  /* Now, check to see if this function is actually a placement
+     allocation function.  This can happen even when PLACEMENT is NULL
+     because we might have something like:
+
+       struct S { void* operator new (size_t, int i = 0); };
+
+     A call to `new S' will get this allocation function, even though
+     there is no explicit placement argument.  If there is more than
+     one argument, or there are variable arguments, then this is a
+     placement allocation function.  */
+  placement_allocation_fn_p
+    = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1
+       || varargs_function_p (alloc_fn));
+
   if (warn_aligned_new
-      && TYPE_ALIGN (elt_type) > max_align_t_align ()
+      && !placement_allocation_fn_p
+      && TYPE_ALIGN (elt_type) > malloc_alignment ()
       && (warn_aligned_new > 1
          || CP_DECL_CONTEXT (alloc_fn) == global_namespace)
       && !aligned_allocation_fn_p (alloc_fn))
@@ -3036,20 +3131,6 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
   while (TREE_CODE (alloc_call) == COMPOUND_EXPR)
     alloc_call = TREE_OPERAND (alloc_call, 1);
 
-  /* Now, check to see if this function is actually a placement
-     allocation function.  This can happen even when PLACEMENT is NULL
-     because we might have something like:
-
-       struct S { void* operator new (size_t, int i = 0); };
-
-     A call to `new S' will get this allocation function, even though
-     there is no explicit placement argument.  If there is more than
-     one argument, or there are variable arguments, then this is a
-     placement allocation function.  */
-  placement_allocation_fn_p
-    = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1
-       || varargs_function_p (alloc_fn));
-
   /* Preevaluate the placement args so that we don't reevaluate them for a
      placement delete.  */
   if (placement_allocation_fn_p)
@@ -3219,8 +3300,10 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
            }
          else if (explicit_value_init_p)
            {
-             /* Something like `new int()'.  */
-             tree val = build_value_init (type, complain);
+             /* Something like `new int()'.  NO_CLEANUP is needed so
+                we don't try and build a (possibly ill-formed)
+                destructor.  */
+             tree val = build_value_init (type, complain | tf_no_cleanup);
              if (val == error_mark_node)
                return error_mark_node;
              init_expr = build2 (INIT_EXPR, type, init_expr, val);
@@ -3237,7 +3320,19 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
              init_expr = cp_build_modify_expr (input_location, init_expr,
                                                INIT_EXPR, ie, complain);
            }
-         stable = stabilize_init (init_expr, &init_preeval_expr);
+         /* If the initializer uses C++14 aggregate NSDMI that refer to the
+            object being initialized, replace them now and don't try to
+            preevaluate.  */
+         bool had_placeholder = false;
+         if (cxx_dialect >= cxx14
+             && !processing_template_decl
+             && TREE_CODE (init_expr) == INIT_EXPR)
+           TREE_OPERAND (init_expr, 1)
+             = replace_placeholders (TREE_OPERAND (init_expr, 1),
+                                     TREE_OPERAND (init_expr, 0),
+                                     &had_placeholder);
+         stable = (!had_placeholder
+                   && stabilize_init (init_expr, &init_preeval_expr));
        }
 
       if (init_expr == error_mark_node)
@@ -3383,15 +3478,19 @@ build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
   if (type == error_mark_node)
     return error_mark_node;
 
-  if (nelts == NULL_TREE && vec_safe_length (*init) == 1
+  if (nelts == NULL_TREE
       /* Don't do auto deduction where it might affect mangling.  */
       && (!processing_template_decl || at_function_scope_p ()))
     {
       tree auto_node = type_uses_auto (type);
       if (auto_node)
        {
-         tree d_init = (**init)[0];
-         d_init = resolve_nondeduced_context (d_init, complain);
+         tree d_init = NULL_TREE;
+         if (vec_safe_length (*init) == 1)
+           {
+             d_init = (**init)[0];
+             d_init = resolve_nondeduced_context (d_init, complain);
+           }
          type = do_auto_deduction (type, d_init, auto_node);
        }
     }
@@ -3409,7 +3508,17 @@ build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
       orig_placement = make_tree_vector_copy (*placement);
       orig_nelts = nelts;
       if (*init)
-       orig_init = make_tree_vector_copy (*init);
+       {
+         orig_init = make_tree_vector_copy (*init);
+         /* Also copy any CONSTRUCTORs in *init, since reshape_init and
+            digest_init clobber them in place.  */
+         for (unsigned i = 0; i < orig_init->length(); ++i)
+           {
+             tree e = (**init)[i];
+             if (TREE_CODE (e) == CONSTRUCTOR)
+               (**init)[i] = copy_node (e);
+           }
+       }
 
       make_args_non_dependent (*placement);
       if (nelts)
@@ -3793,6 +3902,18 @@ build_vec_init (tree base, tree maxindex, tree init,
       && from_array != 2)
     init = TARGET_EXPR_INITIAL (init);
 
+  bool direct_init = false;
+  if (from_array && init && BRACE_ENCLOSED_INITIALIZER_P (init)
+      && CONSTRUCTOR_NELTS (init) == 1)
+    {
+      tree elt = CONSTRUCTOR_ELT (init, 0)->value;
+      if (TREE_CODE (TREE_TYPE (elt)) == ARRAY_TYPE)
+       {
+         direct_init = DIRECT_LIST_INIT_P (init);
+         init = elt;
+       }
+    }
+
   /* If we have a braced-init-list, make sure that the array
      is big enough for all the initializers.  */
   bool length_check = (init && TREE_CODE (init) == CONSTRUCTOR
@@ -4097,6 +4218,8 @@ build_vec_init (tree base, tree maxindex, tree init,
              from = build1 (INDIRECT_REF, itype, base2);
              if (xvalue)
                from = move (from);
+             if (direct_init)
+               from = build_tree_list (NULL_TREE, from);
            }
          else
            from = NULL_TREE;
@@ -4536,7 +4659,8 @@ push_base_cleanups (void)
   vec<tree, va_gc> *vbases;
 
   /* Run destructors for all virtual baseclasses.  */
-  if (CLASSTYPE_VBASECLASSES (current_class_type))
+  if (!ABSTRACT_CLASS_TYPE_P (current_class_type)
+      && CLASSTYPE_VBASECLASSES (current_class_type))
     {
       tree cond = (condition_conversion
                   (build2 (BIT_AND_EXPR, integer_type_node,