Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

More adjustments to allow for explicit object parameters in lambdas.  This
has no practical effect until that patch goes in, but applying this
separately seems reasonable.

gcc/cp/ChangeLog:

        * semantics.cc (finish_non_static_data_member)
        (finish_decltype_type, capture_decltype):
        Handle deduced closure parameter.
---
 gcc/cp/semantics.cc | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc
index 36b57ac9524..fbbc18336a0 100644
--- a/gcc/cp/semantics.cc
+++ b/gcc/cp/semantics.cc
@@ -2262,6 +2262,16 @@ finish_non_static_data_member (tree decl, tree object, 
tree qualifying_scope,
       else if (PACK_EXPANSION_P (type))
        /* Don't bother trying to represent this.  */
        type = NULL_TREE;
+      else if (WILDCARD_TYPE_P (TREE_TYPE (object)))
+       /* We don't know what the eventual quals will be, so punt until
+          instantiation time.
+
+          This can happen when called from build_capture_proxy for an explicit
+          object lambda.  It's a bit marginal to call this function in that
+          case, since this function is for references to members of 'this',
+          but the deduced type is required to be derived from the closure
+          type, so it works.  */
+       type = NULL_TREE;
       else
        {
          /* Set the cv qualifiers.  */
@@ -11682,6 +11692,7 @@ finish_decltype_type (tree expr, bool 
id_expression_or_member_access_p,
      A<decltype(sizeof(T))>::U doesn't require 'typename'.  */
   if (instantiation_dependent_uneval_expression_p (expr))
     {
+    dependent:
       type = cxx_make_type (DECLTYPE_TYPE);
       DECLTYPE_TYPE_EXPR (type) = expr;
       DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (type)
@@ -11856,7 +11867,11 @@ finish_decltype_type (tree expr, bool 
id_expression_or_member_access_p,
       if (outer_automatic_var_p (STRIP_REFERENCE_REF (expr))
          && current_function_decl
          && LAMBDA_FUNCTION_P (current_function_decl))
-       type = capture_decltype (STRIP_REFERENCE_REF (expr));
+       {
+         type = capture_decltype (STRIP_REFERENCE_REF (expr));
+         if (!type)
+           goto dependent;
+       }
       else if (error_operand_p (expr))
        type = error_mark_node;
       else if (expr == current_class_ptr)
@@ -12754,7 +12769,8 @@ apply_deduced_return_type (tree fco, tree return_type)
 
 /* DECL is a local variable or parameter from the surrounding scope of a
    lambda-expression.  Returns the decltype for a use of the capture field
-   for DECL even if it hasn't been captured yet.  */
+   for DECL even if it hasn't been captured yet.  Or NULL_TREE if we can't give
+   a correct answer at this point and we should build a DECLTYPE_TYPE.  */
 
 static tree
 capture_decltype (tree decl)
@@ -12792,9 +12808,11 @@ capture_decltype (tree decl)
 
   if (!TYPE_REF_P (type))
     {
-      int quals = cp_type_quals (type);
       tree obtype = TREE_TYPE (DECL_ARGUMENTS (current_function_decl));
-      gcc_checking_assert (!WILDCARD_TYPE_P (non_reference (obtype)));
+      if (WILDCARD_TYPE_P (non_reference (obtype)))
+       /* We don't know what the eventual obtype quals will be.  */
+       return NULL_TREE;
+      int quals = cp_type_quals (type);
       if (INDIRECT_TYPE_P (obtype))
        quals |= cp_type_quals (TREE_TYPE (obtype));
       type = cp_build_qualified_type (type, quals);

base-commit: f2c52c0dfde581461959b0e2b423ad106aadf179
-- 
2.39.3

Reply via email to