OSDN Git Service

Fix PR c++/43704
[pf3gnuchains/gcc-fork.git] / gcc / cp / semantics.c
index 3e39f37..589241f 100644 (file)
@@ -4,7 +4,7 @@
    and during the instantiation of template functions.
 
    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
    and during the instantiation of template functions.
 
    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-                2008, 2009 Free Software Foundation, Inc.
+                2008, 2009, 2010 Free Software Foundation, Inc.
    Written by Mark Mitchell (mmitchell@usa.net) based on code found
    formerly in parse.y and pt.c.
 
    Written by Mark Mitchell (mmitchell@usa.net) based on code found
    formerly in parse.y and pt.c.
 
@@ -546,10 +546,8 @@ finish_goto_stmt (tree destination)
     TREE_USED (destination) = 1;
   else
     {
     TREE_USED (destination) = 1;
   else
     {
-      /* The DESTINATION is being used as an rvalue.  */
       if (!processing_template_decl)
        {
       if (!processing_template_decl)
        {
-         destination = decay_conversion (destination);
          destination = cp_convert (ptr_type_node, destination);
          if (error_operand_p (destination))
            return NULL_TREE;
          destination = cp_convert (ptr_type_node, destination);
          if (error_operand_p (destination))
            return NULL_TREE;
@@ -1240,6 +1238,8 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
             otherwise we'll get an error.  Gross, but ...  */
          STRIP_NOPS (operand);
 
             otherwise we'll get an error.  Gross, but ...  */
          STRIP_NOPS (operand);
 
+         operand = mark_lvalue_use (operand);
+
          if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
            operand = error_mark_node;
 
          if (!lvalue_or_else (operand, lv_asm, tf_warning_or_error))
            operand = error_mark_node;
 
@@ -1254,7 +1254,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
                     effectively const.  */
                  || (CLASS_TYPE_P (TREE_TYPE (operand))
                      && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
                     effectively const.  */
                  || (CLASS_TYPE_P (TREE_TYPE (operand))
                      && C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
-           readonly_error (operand, "assignment (via 'asm' output)");
+           readonly_error (operand, REK_ASSIGNMENT_ASM);
 
          constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
          oconstraints[i] = constraint;
 
          constraint = TREE_STRING_POINTER (TREE_VALUE (TREE_PURPOSE (t)));
          oconstraints[i] = constraint;
@@ -1426,17 +1426,18 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
 {
   gcc_assert (TREE_CODE (decl) == FIELD_DECL);
 
 {
   gcc_assert (TREE_CODE (decl) == FIELD_DECL);
 
-  if (!object && cp_unevaluated_operand != 0)
+  if (!object)
     {
     {
-      /* DR 613: Can use non-static data members without an associated
-         object in sizeof/decltype/alignof.  */
       tree scope = qualifying_scope;
       if (scope == NULL_TREE)
        scope = context_for_name_lookup (decl);
       object = maybe_dummy_object (scope, NULL);
     }
 
       tree scope = qualifying_scope;
       if (scope == NULL_TREE)
        scope = context_for_name_lookup (decl);
       object = maybe_dummy_object (scope, NULL);
     }
 
-  if (!object)
+  /* DR 613: Can use non-static data members without an associated
+     object in sizeof/decltype/alignof.  */
+  if (is_dummy_object (object) && cp_unevaluated_operand == 0
+      && (!processing_template_decl || !current_class_ref))
     {
       if (current_function_decl
          && DECL_STATIC_FUNCTION_P (current_function_decl))
     {
       if (current_function_decl
          && DECL_STATIC_FUNCTION_P (current_function_decl))
@@ -1448,19 +1449,6 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
       return error_mark_node;
     }
 
       return error_mark_node;
     }
 
-  /* If decl is a non-capture field and object has a lambda type,
-     then we have a reference to a member of 'this' from a
-     lambda inside a non-static member function, and we must get to decl
-     through the 'this' capture.  If decl is not a member of that object,
-     either, then its access will still fail later.  */
-  if (LAMBDA_TYPE_P (TREE_TYPE (object))
-      && !LAMBDA_TYPE_P (DECL_CONTEXT (decl)))
-    object = cp_build_indirect_ref (lambda_expr_this_capture
-                                   (CLASSTYPE_LAMBDA_EXPR
-                                    (TREE_TYPE (object))),
-                                    /*errorstring=*/"",
-                                    /*complain=*/tf_warning_or_error);
-
   if (current_class_ptr)
     TREE_USED (current_class_ptr) = 1;
   if (processing_template_decl && !qualifying_scope)
   if (current_class_ptr)
     TREE_USED (current_class_ptr) = 1;
   if (processing_template_decl && !qualifying_scope)
@@ -1485,33 +1473,17 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
 
       return build_min (COMPONENT_REF, type, object, decl, NULL_TREE);
     }
 
       return build_min (COMPONENT_REF, type, object, decl, NULL_TREE);
     }
+  /* If PROCESSING_TEMPLATE_DECL is nonzero here, then
+     QUALIFYING_SCOPE is also non-null.  Wrap this in a SCOPE_REF
+     for now.  */
+  else if (processing_template_decl)
+    return build_qualified_name (TREE_TYPE (decl),
+                                qualifying_scope,
+                                DECL_NAME (decl),
+                                /*template_p=*/false);
   else
     {
       tree access_type = TREE_TYPE (object);
   else
     {
       tree access_type = TREE_TYPE (object);
-      tree lookup_context = context_for_name_lookup (decl);
-
-      while (!DERIVED_FROM_P (lookup_context, access_type))
-       {
-         access_type = TYPE_CONTEXT (access_type);
-         while (access_type && DECL_P (access_type))
-           access_type = DECL_CONTEXT (access_type);
-
-         if (!access_type)
-           {
-             error ("object missing in reference to %q+D", decl);
-             error ("from this location");
-             return error_mark_node;
-           }
-       }
-
-      /* If PROCESSING_TEMPLATE_DECL is nonzero here, then
-        QUALIFYING_SCOPE is also non-null.  Wrap this in a SCOPE_REF
-        for now.  */
-      if (processing_template_decl)
-       return build_qualified_name (TREE_TYPE (decl),
-                                    qualifying_scope,
-                                    DECL_NAME (decl),
-                                    /*template_p=*/false);
 
       perform_or_defer_access_check (TYPE_BINFO (access_type), decl,
                                     decl);
 
       perform_or_defer_access_check (TYPE_BINFO (access_type), decl,
                                     decl);
@@ -1532,6 +1504,37 @@ finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
     }
 }
 
     }
 }
 
+/* If we are currently parsing a template and we encountered a typedef
+   TYPEDEF_DECL that is being accessed though CONTEXT, this function
+   adds the typedef to a list tied to the current template.
+   At tempate instantiatin time, that list is walked and access check
+   performed for each typedef.
+   LOCATION is the location of the usage point of TYPEDEF_DECL.  */
+
+void
+add_typedef_to_current_template_for_access_check (tree typedef_decl,
+                                                  tree context,
+                                                 location_t location)
+{
+    tree template_info = NULL;
+    tree cs = current_scope ();
+
+    if (!is_typedef_decl (typedef_decl)
+       || !context
+       || !CLASS_TYPE_P (context)
+       || !cs)
+      return;
+
+    if (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL)
+      template_info = get_template_info (cs);
+
+    if (template_info
+       && TI_TEMPLATE (template_info)
+       && !currently_open_class (context))
+      append_type_to_template_for_access_check (cs, typedef_decl,
+                                               context, location);
+}
+
 /* DECL was the declaration to which a qualified-id resolved.  Issue
    an error message if it is not accessible.  If OBJECT_TYPE is
    non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the
 /* DECL was the declaration to which a qualified-id resolved.  Issue
    an error message if it is not accessible.  If OBJECT_TYPE is
    non-NULL, we have just seen `x->' or `x.' and OBJECT_TYPE is the
@@ -1550,27 +1553,11 @@ check_accessibility_of_qualified_id (tree decl,
      add it to a list tied to the template.
      At template instantiation time, that list will be walked and
      access check performed.  */
      add it to a list tied to the template.
      At template instantiation time, that list will be walked and
      access check performed.  */
-  if (is_typedef_decl (decl))
-    {
-      /* This the scope through which type_decl is accessed.
-        It will be useful information later to do access check for
-        type_decl usage.  */
-      tree scope = nested_name_specifier
-      ?  nested_name_specifier
-      : DECL_CONTEXT (decl);
-      tree templ_info = NULL;
-      tree cs = current_scope ();
-
-      if (cs && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
-       templ_info = get_template_info (cs);
-
-      if (templ_info
-         && TI_TEMPLATE (templ_info)
-         && scope
-         && CLASS_TYPE_P (scope)
-         && !currently_open_class (scope))
-       append_type_to_template_for_access_check (current_scope (), decl, scope);
-    }
+  add_typedef_to_current_template_for_access_check (decl,
+                                                   nested_name_specifier
+                                                   ? nested_name_specifier
+                                                   : DECL_CONTEXT (decl),
+                                                   input_location);
 
   /* If we're not checking, return immediately.  */
   if (deferred_access_no_check)
 
   /* If we're not checking, return immediately.  */
   if (deferred_access_no_check)
@@ -1671,24 +1658,21 @@ finish_qualified_id_expr (tree qualifying_class,
   else if (TREE_CODE (expr) == FIELD_DECL)
     {
       push_deferring_access_checks (dk_no_check);
   else if (TREE_CODE (expr) == FIELD_DECL)
     {
       push_deferring_access_checks (dk_no_check);
-      expr = finish_non_static_data_member (expr, current_class_ref,
+      expr = finish_non_static_data_member (expr, NULL_TREE,
                                            qualifying_class);
       pop_deferring_access_checks ();
     }
   else if (BASELINK_P (expr) && !processing_template_decl)
     {
                                            qualifying_class);
       pop_deferring_access_checks ();
     }
   else if (BASELINK_P (expr) && !processing_template_decl)
     {
-      tree fns;
+      tree ob;
 
       /* See if any of the functions are non-static members.  */
 
       /* See if any of the functions are non-static members.  */
-      fns = BASELINK_FUNCTIONS (expr);
-      if (TREE_CODE (fns) == TEMPLATE_ID_EXPR)
-       fns = TREE_OPERAND (fns, 0);
       /* If so, the expression may be relative to 'this'.  */
       /* If so, the expression may be relative to 'this'.  */
-      if (!shared_member_p (fns)
-         && current_class_ref
-         && DERIVED_FROM_P (qualifying_class, TREE_TYPE (current_class_ref)))
+      if (!shared_member_p (expr)
+         && (ob = maybe_dummy_object (qualifying_class, NULL),
+             !is_dummy_object (ob)))
        expr = (build_class_member_access_expr
        expr = (build_class_member_access_expr
-               (maybe_dummy_object (qualifying_class, NULL),
+               (ob,
                 expr,
                 BASELINK_ACCESS_BINFO (expr),
                 /*preserve_reference=*/false,
                 expr,
                 BASELINK_ACCESS_BINFO (expr),
                 /*preserve_reference=*/false,
@@ -1833,6 +1817,35 @@ stmt_expr_value_expr (tree stmt_expr)
   return t;
 }
 
   return t;
 }
 
+/* Return TRUE iff EXPR_STMT is an empty list of
+   expression statements.  */
+
+bool
+empty_expr_stmt_p (tree expr_stmt)
+{
+  tree body = NULL_TREE;
+
+  if (expr_stmt == void_zero_node)
+    return true;
+
+  if (expr_stmt)
+    {
+      if (TREE_CODE (expr_stmt) == EXPR_STMT)
+       body = EXPR_STMT_EXPR (expr_stmt);
+      else if (TREE_CODE (expr_stmt) == STATEMENT_LIST)
+       body = expr_stmt;
+    }
+
+  if (body)
+    {
+      if (TREE_CODE (body) == STATEMENT_LIST)
+       return tsi_end_p (tsi_start (body));
+      else
+       return empty_expr_stmt_p (body);
+    }
+  return false;
+}
+
 /* Perform Koenig lookup.  FN is the postfix-expression representing
    the function (or functions) to call; ARGS are the arguments to the
    call.  Returns the functions to be considered by overload
 /* Perform Koenig lookup.  FN is the postfix-expression representing
    the function (or functions) to call; ARGS are the arguments to the
    call.  Returns the functions to be considered by overload
@@ -1961,31 +1974,18 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
           . operator.... [Otherwise] a contrived object of type T
           becomes the implied object argument.
 
           . operator.... [Otherwise] a contrived object of type T
           becomes the implied object argument.
 
-       This paragraph is unclear about this situation:
+       In this situation:
 
          struct A { void f(); };
          struct B : public A {};
          struct C : public A { void g() { B::f(); }};
 
 
          struct A { void f(); };
          struct B : public A {};
          struct C : public A { void g() { B::f(); }};
 
-       In particular, for `B::f', this paragraph does not make clear
-       whether "the class of that member function" refers to `A' or
-       to `B'.  We believe it refers to `B'.  */
-      if (current_class_type
-         && DERIVED_FROM_P (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
-                            current_class_type)
-         && current_class_ref)
-       object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
-                                    NULL);
-      else
-       {
-         tree representative_fn;
+       "the class of that member function" refers to `A'.  But 11.2
+       [class.access.base] says that we need to convert 'this' to B* as
+       part of the access, so we pass 'B' to maybe_dummy_object.  */
 
 
-         representative_fn = BASELINK_FUNCTIONS (fn);
-         if (TREE_CODE (representative_fn) == TEMPLATE_ID_EXPR)
-           representative_fn = TREE_OPERAND (representative_fn, 0);
-         representative_fn = get_first_fn (representative_fn);
-         object = build_dummy_object (DECL_CONTEXT (representative_fn));
-       }
+      object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
+                                  NULL);
 
       if (processing_template_decl)
        {
 
       if (processing_template_decl)
        {
@@ -2218,6 +2218,7 @@ finish_compound_literal (tree type, tree compound_literal)
       tree decl = create_temporary_var (type);
       DECL_INITIAL (decl) = compound_literal;
       TREE_STATIC (decl) = 1;
       tree decl = create_temporary_var (type);
       DECL_INITIAL (decl) = compound_literal;
       TREE_STATIC (decl) = 1;
+      cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
       decl = pushdecl_top_level (decl);
       DECL_NAME (decl) = make_anon_name ();
       SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
       decl = pushdecl_top_level (decl);
       DECL_NAME (decl) = make_anon_name ();
       SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
@@ -2329,6 +2330,26 @@ begin_class_definition (tree t, tree attributes)
       error ("definition of %q#T inside template parameter list", t);
       return error_mark_node;
     }
       error ("definition of %q#T inside template parameter list", t);
       return error_mark_node;
     }
+
+  /* According to the C++ ABI, decimal classes defined in ISO/IEC TR 24733
+     are passed the same as decimal scalar types.  */
+  if (TREE_CODE (t) == RECORD_TYPE
+      && !processing_template_decl)
+    {
+      tree ns = TYPE_CONTEXT (t);
+      if (ns && TREE_CODE (ns) == NAMESPACE_DECL
+         && DECL_CONTEXT (ns) == std_node
+         && DECL_NAME (ns)
+         && !strcmp (IDENTIFIER_POINTER (DECL_NAME (ns)), "decimal"))
+       {
+         const char *n = TYPE_NAME_STRING (t);
+         if ((strcmp (n, "decimal32") == 0)
+             || (strcmp (n, "decimal64") == 0)
+             || (strcmp (n, "decimal128") == 0))
+           TYPE_TRANSPARENT_AGGR (t) = 1;
+       }
+    }
+
   /* A non-implicit typename comes from code like:
 
        template <typename T> struct A {
   /* A non-implicit typename comes from code like:
 
        template <typename T> struct A {
@@ -2347,9 +2368,6 @@ begin_class_definition (tree t, tree attributes)
       pushtag (make_anon_name (), t, /*tag_scope=*/ts_current);
     }
 
       pushtag (make_anon_name (), t, /*tag_scope=*/ts_current);
     }
 
-  /* Update the location of the decl.  */
-  DECL_SOURCE_LOCATION (TYPE_NAME (t)) = input_location;
-
   if (TYPE_BEING_DEFINED (t))
     {
       t = make_class_type (TREE_CODE (t));
   if (TYPE_BEING_DEFINED (t))
     {
       t = make_class_type (TREE_CODE (t));
@@ -3014,7 +3032,7 @@ finish_id_expression (tree id_expression,
                 already.  Turn off checking to avoid duplicate errors.  */
              push_deferring_access_checks (dk_no_check);
              decl = finish_non_static_data_member
                 already.  Turn off checking to avoid duplicate errors.  */
              push_deferring_access_checks (dk_no_check);
              decl = finish_non_static_data_member
-                      (decl, current_class_ref,
+                      (decl, NULL_TREE,
                        /*qualifying_scope=*/NULL_TREE);
              pop_deferring_access_checks ();
              return decl;
                        /*qualifying_scope=*/NULL_TREE);
              pop_deferring_access_checks ();
              return decl;
@@ -3095,7 +3113,7 @@ finish_id_expression (tree id_expression,
             Access checking has been performed during name lookup
             already.  Turn off checking to avoid duplicate errors.  */
          push_deferring_access_checks (dk_no_check);
             Access checking has been performed during name lookup
             already.  Turn off checking to avoid duplicate errors.  */
          push_deferring_access_checks (dk_no_check);
-         decl = finish_non_static_data_member (decl, current_class_ref,
+         decl = finish_non_static_data_member (decl, NULL_TREE,
                                                /*qualifying_scope=*/NULL_TREE);
          pop_deferring_access_checks ();
        }
                                                /*qualifying_scope=*/NULL_TREE);
          pop_deferring_access_checks ();
        }
@@ -3103,10 +3121,7 @@ finish_id_expression (tree id_expression,
        {
          tree first_fn;
 
        {
          tree first_fn;
 
-         first_fn = decl;
-         if (TREE_CODE (first_fn) == TEMPLATE_ID_EXPR)
-           first_fn = TREE_OPERAND (first_fn, 0);
-         first_fn = get_first_fn (first_fn);
+         first_fn = get_first_fn (decl);
          if (TREE_CODE (first_fn) == TEMPLATE_DECL)
            first_fn = DECL_TEMPLATE_RESULT (first_fn);
 
          if (TREE_CODE (first_fn) == TEMPLATE_DECL)
            first_fn = DECL_TEMPLATE_RESULT (first_fn);
 
@@ -3168,6 +3183,8 @@ finish_typeof (tree expr)
       return type;
     }
 
       return type;
     }
 
+  expr = mark_type_use (expr);
+
   type = unlowered_expr_type (expr);
 
   if (!type || type == unknown_type_node)
   type = unlowered_expr_type (expr);
 
   if (!type || type == unknown_type_node)
@@ -3193,7 +3210,7 @@ finish_offsetof (tree expr)
     }
   if (TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE
       || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
     }
   if (TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE
       || TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
-      || TREE_CODE (TREE_TYPE (expr)) == UNKNOWN_TYPE)
+      || TREE_TYPE (expr) == unknown_type_node)
     {
       if (TREE_CODE (expr) == COMPONENT_REF
          || TREE_CODE (expr) == COMPOUND_EXPR)
     {
       if (TREE_CODE (expr) == COMPONENT_REF
          || TREE_CODE (expr) == COMPOUND_EXPR)
@@ -3255,7 +3272,7 @@ simplify_aggr_init_expr (tree *tp)
         expand_call{,_inline}.  */
       cxx_mark_addressable (slot);
       CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
         expand_call{,_inline}.  */
       cxx_mark_addressable (slot);
       CALL_EXPR_RETURN_SLOT_OPT (call_expr) = true;
-      call_expr = build2 (MODIFY_EXPR, TREE_TYPE (call_expr), slot, call_expr);
+      call_expr = build2 (INIT_EXPR, TREE_TYPE (call_expr), slot, call_expr);
     }
   else if (style == pcc)
     {
     }
   else if (style == pcc)
     {
@@ -3320,8 +3337,8 @@ emit_associated_thunks (tree fn)
 
 /* Generate RTL for FN.  */
 
 
 /* Generate RTL for FN.  */
 
-void
-expand_or_defer_fn (tree fn)
+bool
+expand_or_defer_fn_1 (tree fn)
 {
   /* When the parser calls us after finishing the body of a template
      function, we don't really want to expand the body.  */
 {
   /* When the parser calls us after finishing the body of a template
      function, we don't really want to expand the body.  */
@@ -3335,7 +3352,7 @@ expand_or_defer_fn (tree fn)
         is not a GC root.  */
       if (!function_depth)
        ggc_collect ();
         is not a GC root.  */
       if (!function_depth)
        ggc_collect ();
-      return;
+      return false;
     }
 
   gcc_assert (DECL_SAVED_TREE (fn));
     }
 
   gcc_assert (DECL_SAVED_TREE (fn));
@@ -3348,7 +3365,7 @@ expand_or_defer_fn (tree fn)
         it out, even though we haven't.  */
       TREE_ASM_WRITTEN (fn) = 1;
       DECL_SAVED_TREE (fn) = NULL_TREE;
         it out, even though we haven't.  */
       TREE_ASM_WRITTEN (fn) = 1;
       DECL_SAVED_TREE (fn) = NULL_TREE;
-      return;
+      return false;
     }
 
   /* We make a decision about linkage for these functions at the end
     }
 
   /* We make a decision about linkage for these functions at the end
@@ -3387,7 +3404,9 @@ expand_or_defer_fn (tree fn)
         this function as needed so that finish_file will make sure to
         output it later.  Similarly, all dllexport'd functions must
         be emitted; there may be callers in other DLLs.  */
         this function as needed so that finish_file will make sure to
         output it later.  Similarly, all dllexport'd functions must
         be emitted; there may be callers in other DLLs.  */
-      if ((flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn))
+      if ((flag_keep_inline_functions
+          && DECL_DECLARED_INLINE_P (fn)
+          && !DECL_REALLY_EXTERN (fn))
          || lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))
        mark_needed (fn);
     }
          || lookup_attribute ("dllexport", DECL_ATTRIBUTES (fn)))
        mark_needed (fn);
     }
@@ -3395,14 +3414,24 @@ expand_or_defer_fn (tree fn)
   /* There's no reason to do any of the work here if we're only doing
      semantic analysis; this code just generates RTL.  */
   if (flag_syntax_only)
   /* There's no reason to do any of the work here if we're only doing
      semantic analysis; this code just generates RTL.  */
   if (flag_syntax_only)
-    return;
+    return false;
 
 
-  function_depth++;
+  return true;
+}
 
 
-  /* Expand or defer, at the whim of the compilation unit manager.  */
-  cgraph_finalize_function (fn, function_depth > 1);
+void
+expand_or_defer_fn (tree fn)
+{
+  if (expand_or_defer_fn_1 (fn))
+    {
+      function_depth++;
 
 
-  function_depth--;
+      /* Expand or defer, at the whim of the compilation unit manager.  */
+      cgraph_finalize_function (fn, function_depth > 1);
+      emit_associated_thunks (fn);
+
+      function_depth--;
+    }
 }
 
 struct nrv_data
 }
 
 struct nrv_data
@@ -4641,10 +4670,8 @@ finish_static_assert (tree condition, tree message, location_t location,
     }
 }
 \f
     }
 }
 \f
-/* Returns decltype((EXPR)) for cases where we can drop the decltype and
-   just return the type even though EXPR is a type-dependent expression.
-   The ABI specifies which cases this applies to, which is a subset of the
-   possible cases.  */
+/* Returns the type of EXPR for cases where we can determine it even though
+   EXPR is a type-dependent expression.  */
 
 tree
 describable_type (tree expr)
 
 tree
 describable_type (tree expr)
@@ -4668,8 +4695,7 @@ describable_type (tree expr)
     case PARM_DECL:
     case RESULT_DECL:
     case FUNCTION_DECL:
     case PARM_DECL:
     case RESULT_DECL:
     case FUNCTION_DECL:
-      /* Named rvalue reference becomes lvalue.  */
-      type = build_reference_type (non_reference (TREE_TYPE (expr)));
+      return TREE_TYPE (expr);
       break;
 
     case NEW_EXPR:
       break;
 
     case NEW_EXPR:
@@ -4728,7 +4754,13 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
       return error_mark_node;
     }
 
       return error_mark_node;
     }
 
-  if (type_dependent_expression_p (expr))
+  if (type_dependent_expression_p (expr)
+      /* In a template, a COMPONENT_REF has an IDENTIFIER_NODE for op1 even
+        if it isn't dependent, so that we can check access control at
+        instantiation time, so defer the decltype as well (PR 42277).  */
+      || (id_expression_or_member_access_p
+         && processing_template_decl
+         && TREE_CODE (expr) == COMPONENT_REF))
     {
       if (id_expression_or_member_access_p)
        {
     {
       if (id_expression_or_member_access_p)
        {
@@ -4751,6 +4783,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
       if (type && !type_uses_auto (type))
        return type;
 
       if (type && !type_uses_auto (type))
        return type;
 
+    treat_as_dependent:
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
       DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
       DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)
@@ -4763,6 +4796,14 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
   /* The type denoted by decltype(e) is defined as follows:  */
 
   expr = resolve_nondeduced_context (expr);
   /* The type denoted by decltype(e) is defined as follows:  */
 
   expr = resolve_nondeduced_context (expr);
+
+  /* To get the size of a static data member declared as an array of
+     unknown bound, we need to instantiate it.  */
+  if (TREE_CODE (expr) == VAR_DECL
+      && VAR_HAD_UNKNOWN_BOUND (expr)
+      && DECL_TEMPLATE_INSTANTIATION (expr))
+    instantiate_decl (expr, /*defer_ok*/true, /*expl_inst_mem*/false);
+
   if (id_expression_or_member_access_p)
     {
       /* If e is an id-expression or a class member access (5.2.5
   if (id_expression_or_member_access_p)
     {
       /* If e is an id-expression or a class member access (5.2.5
@@ -4821,6 +4862,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
         case PARM_DECL:
         case RESULT_DECL:
         case TEMPLATE_PARM_INDEX:
         case PARM_DECL:
         case RESULT_DECL:
         case TEMPLATE_PARM_INDEX:
+         expr = mark_type_use (expr);
           type = TREE_TYPE (expr);
           break;
 
           type = TREE_TYPE (expr);
           break;
 
@@ -4829,6 +4871,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
           break;
 
         case COMPONENT_REF:
           break;
 
         case COMPONENT_REF:
+         mark_type_use (expr);
           type = is_bitfield_expr_with_lowered_type (expr);
           if (!type)
             type = TREE_TYPE (TREE_OPERAND (expr, 1));
           type = is_bitfield_expr_with_lowered_type (expr);
           if (!type)
             type = TREE_TYPE (TREE_OPERAND (expr, 1));
@@ -4878,6 +4921,11 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p)
                   && (TREE_CODE (TREE_TYPE (target_type)) == FUNCTION_TYPE
                       || TREE_CODE (TREE_TYPE (target_type)) == METHOD_TYPE))
                 type = TREE_TYPE (TREE_TYPE (target_type));
                   && (TREE_CODE (TREE_TYPE (target_type)) == FUNCTION_TYPE
                       || TREE_CODE (TREE_TYPE (target_type)) == METHOD_TYPE))
                 type = TREE_TYPE (TREE_TYPE (target_type));
+             else if (processing_template_decl)
+               /* Within a template finish_call_expr doesn't resolve
+                  CALL_EXPR_FN, so even though this decltype isn't really
+                  dependent let's defer resolving it.  */
+               goto treat_as_dependent;
               else
                 sorry ("unable to determine the declared type of expression %<%E%>",
                        expr);
               else
                 sorry ("unable to determine the declared type of expression %<%E%>",
                        expr);
@@ -5350,6 +5398,9 @@ build_lambda_object (tree lambda_expr)
       tree field = TREE_PURPOSE (node);
       tree val = TREE_VALUE (node);
 
       tree field = TREE_PURPOSE (node);
       tree val = TREE_VALUE (node);
 
+      if (DECL_P (val))
+       mark_used (val);
+
       /* Mere mortals can't copy arrays with aggregate initialization, so
         do some magic to make it work here.  */
       if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
       /* Mere mortals can't copy arrays with aggregate initialization, so
         do some magic to make it work here.  */
       if (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE)
@@ -5430,6 +5481,11 @@ tree
 lambda_return_type (tree expr)
 {
   tree type;
 lambda_return_type (tree expr)
 {
   tree type;
+  if (BRACE_ENCLOSED_INITIALIZER_P (expr))
+    {
+      warning (0, "cannot deduce lambda return type from a braced-init-list");
+      return void_type_node;
+    }
   if (type_dependent_expression_p (expr))
     {
       type = cxx_make_type (DECLTYPE_TYPE);
   if (type_dependent_expression_p (expr))
     {
       type = cxx_make_type (DECLTYPE_TYPE);
@@ -5504,7 +5560,7 @@ apply_lambda_return_type (tree lambda, tree return_type)
 
   /* TREE_TYPE (FUNCTION_DECL) == METHOD_TYPE
      TREE_TYPE (METHOD_TYPE)   == return-type  */
 
   /* TREE_TYPE (FUNCTION_DECL) == METHOD_TYPE
      TREE_TYPE (METHOD_TYPE)   == return-type  */
-  TREE_TYPE (TREE_TYPE (fco)) = return_type;
+  TREE_TYPE (fco) = change_return_type (return_type, TREE_TYPE (fco));
 
   result = DECL_RESULT (fco);
   if (result == NULL_TREE)
 
   result = DECL_RESULT (fco);
   if (result == NULL_TREE)
@@ -5609,8 +5665,9 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
        always visible.  */
     DECL_NORMAL_CAPTURE_P (member) = true;
 
        always visible.  */
     DECL_NORMAL_CAPTURE_P (member) = true;
 
-  /* Add it to the appropriate closure class.  */
-  finish_member_declaration (member);
+  /* Add it to the appropriate closure class if we've started it.  */
+  if (current_class_type && current_class_type == TREE_TYPE (lambda))
+    finish_member_declaration (member);
 
   LAMBDA_EXPR_CAPTURE_LIST (lambda)
     = tree_cons (member, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda));
 
   LAMBDA_EXPR_CAPTURE_LIST (lambda)
     = tree_cons (member, initializer, LAMBDA_EXPR_CAPTURE_LIST (lambda));
@@ -5625,6 +5682,18 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p,
   return member;
 }
 
   return member;
 }
 
+/* Register all the capture members on the list CAPTURES, which is the
+   LAMBDA_EXPR_CAPTURE_LIST for the lambda after the introducer.  */
+
+void register_capture_members (tree captures)
+{
+  if (captures)
+    {
+      register_capture_members (TREE_CHAIN (captures));
+      finish_member_declaration (TREE_PURPOSE (captures));
+    }
+}
+
 /* Given a FIELD_DECL decl belonging to a closure type, return a
    COMPONENT_REF of it relative to the 'this' parameter of the op() for
    that type.  */
 /* Given a FIELD_DECL decl belonging to a closure type, return a
    COMPONENT_REF of it relative to the 'this' parameter of the op() for
    that type.  */
@@ -5634,7 +5703,7 @@ thisify_lambda_field (tree decl)
 {
   tree context = lambda_function (DECL_CONTEXT (decl));
   tree object = cp_build_indirect_ref (DECL_ARGUMENTS (context),
 {
   tree context = lambda_function (DECL_CONTEXT (decl));
   tree object = cp_build_indirect_ref (DECL_ARGUMENTS (context),
-                                      /*errorstring*/"",
+                                      RO_NULL,
                                       tf_warning_or_error);
   return finish_non_static_data_member (decl, object,
                                        /*qualifying_scope*/NULL_TREE);
                                       tf_warning_or_error);
   return finish_non_static_data_member (decl, object,
                                        /*qualifying_scope*/NULL_TREE);
@@ -5709,10 +5778,7 @@ lambda_expr_this_capture (tree lambda)
            {
              /* An outer lambda has already captured 'this'.  */
              tree cap = LAMBDA_EXPR_THIS_CAPTURE (lambda);
            {
              /* An outer lambda has already captured 'this'.  */
              tree cap = LAMBDA_EXPR_THIS_CAPTURE (lambda);
-             tree lthis
-               = cp_build_indirect_ref (DECL_ARGUMENTS (containing_function),
-                                        "", tf_warning_or_error);
-             init = finish_non_static_data_member (cap, lthis, NULL_TREE);
+             init = thisify_lambda_field (cap);
              break;
            }
 
              break;
            }
 
@@ -5749,7 +5815,7 @@ lambda_expr_this_capture (tree lambda)
       gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda));
 
       result = finish_non_static_data_member (this_capture,
       gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (current_class_ref)) == TREE_TYPE (lambda));
 
       result = finish_non_static_data_member (this_capture,
-                                              current_class_ref,
+                                              NULL_TREE,
                                               /*qualifying_scope=*/NULL_TREE);
 
       /* If 'this' is captured, each use of 'this' is transformed into an
                                               /*qualifying_scope=*/NULL_TREE);
 
       /* If 'this' is captured, each use of 'this' is transformed into an
@@ -5762,4 +5828,177 @@ lambda_expr_this_capture (tree lambda)
   return result;
 }
 
   return result;
 }
 
+/* Returns the method basetype of the innermost non-lambda function, or
+   NULL_TREE if none.  */
+
+tree
+nonlambda_method_basetype (void)
+{
+  tree fn, type;
+  if (!current_class_ref)
+    return NULL_TREE;
+
+  type = current_class_type;
+  if (!LAMBDA_TYPE_P (type))
+    return type;
+
+  /* Find the nearest enclosing non-lambda function.  */
+  fn = TYPE_NAME (type);
+  do
+    fn = decl_function_context (fn);
+  while (fn && LAMBDA_FUNCTION_P (fn));
+
+  if (!fn || !DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+    return NULL_TREE;
+
+  return TYPE_METHOD_BASETYPE (TREE_TYPE (fn));
+}
+
+/* If the closure TYPE has a static op(), also add a conversion to function
+   pointer.  */
+
+void
+maybe_add_lambda_conv_op (tree type)
+{
+  bool nested = (current_function_decl != NULL_TREE);
+  tree callop = lambda_function (type);
+  tree rettype, name, fntype, fn, body, compound_stmt;
+  tree thistype, stattype, statfn, convfn, call, arg;
+  VEC (tree, gc) *argvec;
+
+  if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE)
+    return;
+
+  stattype = build_function_type (TREE_TYPE (TREE_TYPE (callop)),
+                                 FUNCTION_ARG_CHAIN (callop));
+
+  /* First build up the conversion op.  */
+
+  rettype = build_pointer_type (stattype);
+  name = mangle_conv_op_name_for_type (rettype);
+  thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST);
+  fntype = build_method_type_directly (thistype, rettype, void_list_node);
+  fn = convfn = build_lang_decl (FUNCTION_DECL, name, fntype);
+  DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
+
+  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+      && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
+    DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;
+
+  SET_OVERLOADED_OPERATOR_CODE (fn, TYPE_EXPR);
+  grokclassfn (type, fn, NO_SPECIAL);
+  set_linkage_according_to_type (type, fn);
+  rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
+  DECL_IN_AGGR_P (fn) = 1;
+  DECL_ARTIFICIAL (fn) = 1;
+  DECL_NOT_REALLY_EXTERN (fn) = 1;
+  DECL_DECLARED_INLINE_P (fn) = 1;
+  DECL_ARGUMENTS (fn) = build_this_parm (fntype, TYPE_QUAL_CONST);
+  if (nested)
+    DECL_INTERFACE_KNOWN (fn) = 1;
+
+  add_method (type, fn, NULL_TREE);
+
+  /* Generic thunk code fails for varargs; we'll complain in mark_used if
+     the conversion op is used.  */
+  if (varargs_function_p (callop))
+    {
+      DECL_DELETED_FN (fn) = 1;
+      return;
+    }
+
+  /* Now build up the thunk to be returned.  */
+
+  name = get_identifier ("_FUN");
+  fn = statfn = build_lang_decl (FUNCTION_DECL, name, stattype);
+  DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
+  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
+      && DECL_ALIGN (fn) < 2 * BITS_PER_UNIT)
+    DECL_ALIGN (fn) = 2 * BITS_PER_UNIT;
+  grokclassfn (type, fn, NO_SPECIAL);
+  set_linkage_according_to_type (type, fn);
+  rest_of_decl_compilation (fn, toplevel_bindings_p (), at_eof);
+  DECL_IN_AGGR_P (fn) = 1;
+  DECL_ARTIFICIAL (fn) = 1;
+  DECL_NOT_REALLY_EXTERN (fn) = 1;
+  DECL_DECLARED_INLINE_P (fn) = 1;
+  DECL_STATIC_FUNCTION_P (fn) = 1;
+  DECL_ARGUMENTS (fn) = copy_list (TREE_CHAIN (DECL_ARGUMENTS (callop)));
+  for (arg = DECL_ARGUMENTS (fn); arg; arg = TREE_CHAIN (arg))
+    DECL_CONTEXT (arg) = fn;
+  if (nested)
+    DECL_INTERFACE_KNOWN (fn) = 1;
+
+  add_method (type, fn, NULL_TREE);
+
+  if (nested)
+    push_function_context ();
+
+  /* Generate the body of the thunk.  */
+
+  start_preparsed_function (statfn, NULL_TREE,
+                           SF_PRE_PARSED | SF_INCLASS_INLINE);
+  if (DECL_ONE_ONLY (statfn))
+    {
+      /* Put the thunk in the same comdat group as the call op.  */
+      struct cgraph_node *callop_node, *thunk_node;
+      DECL_COMDAT_GROUP (statfn) = DECL_COMDAT_GROUP (callop);
+      callop_node = cgraph_node (callop);
+      thunk_node = cgraph_node (statfn);
+      gcc_assert (callop_node->same_comdat_group == NULL);
+      gcc_assert (thunk_node->same_comdat_group == NULL);
+      callop_node->same_comdat_group = thunk_node;
+      thunk_node->same_comdat_group = callop_node;
+    }
+  body = begin_function_body ();
+  compound_stmt = begin_compound_stmt (0);
+
+  arg = build1 (NOP_EXPR, TREE_TYPE (DECL_ARGUMENTS (callop)),
+               null_pointer_node);
+  argvec = make_tree_vector ();
+  VEC_quick_push (tree, argvec, arg);
+  for (arg = DECL_ARGUMENTS (statfn); arg; arg = TREE_CHAIN (arg))
+    VEC_safe_push (tree, gc, argvec, arg);
+  call = build_call_a (callop, VEC_length (tree, argvec),
+                      VEC_address (tree, argvec));
+  CALL_FROM_THUNK_P (call) = 1;
+  if (MAYBE_CLASS_TYPE_P (TREE_TYPE (call)))
+    call = build_cplus_new (TREE_TYPE (call), call);
+  call = convert_from_reference (call);
+  finish_return_stmt (call);
+
+  finish_compound_stmt (compound_stmt);
+  finish_function_body (body);
+
+  expand_or_defer_fn (finish_function (2));
+
+  /* Generate the body of the conversion op.  */
+
+  start_preparsed_function (convfn, NULL_TREE,
+                           SF_PRE_PARSED | SF_INCLASS_INLINE);
+  if (DECL_ONE_ONLY (statfn))
+    {
+      /* Put the thunk in the same comdat group as the call op.  */
+      struct cgraph_node *callop_node, *thunk_node;
+      DECL_COMDAT_GROUP (statfn) = DECL_COMDAT_GROUP (callop);
+      callop_node = cgraph_node (callop);
+      thunk_node = cgraph_node (statfn);
+      gcc_assert (callop_node->same_comdat_group == NULL);
+      gcc_assert (thunk_node->same_comdat_group == NULL);
+      callop_node->same_comdat_group = thunk_node;
+      thunk_node->same_comdat_group = callop_node;
+    }
+  body = begin_function_body ();
+  compound_stmt = begin_compound_stmt (0);
+
+  finish_return_stmt (decay_conversion (statfn));
+
+  finish_compound_stmt (compound_stmt);
+  finish_function_body (body);
+
+  expand_or_defer_fn (finish_function (2));
+
+  if (nested)
+    pop_function_context ();
+}
 #include "gt-cp-semantics.h"
 #include "gt-cp-semantics.h"