c++: lambda capture and explicit object parm

Message ID 20231201035003.857697-1-jason@redhat.com
State Committed
Commit 73e2bdbf9bed48b2b30691f03e79230bff4850c6
Headers
Series c++: lambda capture and explicit object parm |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm warning Patch is already merged
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 warning Patch is already merged

Commit Message

Jason Merrill Dec. 1, 2023, 3:50 a.m. UTC
  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(-)


base-commit: f2c52c0dfde581461959b0e2b423ad106aadf179
  

Patch

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);