public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-7101] c++: constrained auto in lambda using outer tparms [PR103706]
@ 2022-02-08 13:48 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2022-02-08 13:48 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:34ba3d9a2bf72742b1c150a2dd17d10e3e3f0964

commit r12-7101-g34ba3d9a2bf72742b1c150a2dd17d10e3e3f0964
Author: Patrick Palka <ppalka@redhat.com>
Date:   Tue Feb 8 08:46:13 2022 -0500

    c++: constrained auto in lambda using outer tparms [PR103706]
    
    Here we're crashing during satisfaction of the lambda's placeholder type
    constraints because the constraints depend on the template arguments
    from the enclosing scope, which aren't part of the lambda's DECL_TI_ARGS.
    
    This patch fixes this by making do_auto_deduction consider the
    "regenerating" template arguments of a lambda for satisfaction,
    mirroring what's done in satisfy_declaration_constraints.
    
            PR c++/103706
    
    gcc/cp/ChangeLog:
    
            * constraint.cc (satisfy_declaration_constraints): Use
            lambda_regenerating_args instead.
            * cp-tree.h (lambda_regenerating_args): Declare.
            * pt.cc (lambda_regenerating_args): Define, split out from
            satisfy_declaration_constraints.
            (do_auto_deduction): Use lambda_regenerating_args to obtain the
            full set of outer template arguments for satisfaction when
            inside a lambda.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/concepts-lambda18.C: New test.

Diff:
---
 gcc/cp/constraint.cc                           |  7 ++---
 gcc/cp/cp-tree.h                               |  1 +
 gcc/cp/pt.cc                                   | 39 ++++++++++++++++++++++----
 gcc/testsuite/g++.dg/cpp2a/concepts-lambda18.C | 14 +++++++++
 4 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index cc4df4216ef..b7b9439f34b 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -3154,12 +3154,11 @@ satisfy_declaration_constraints (tree t, sat_info info)
 	 set of template arguments.  Augment this with the outer template
 	 arguments that were used to regenerate the lambda.  */
       gcc_assert (!args || TMPL_ARGS_DEPTH (args) == 1);
-      tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t));
-      tree outer_args = TI_ARGS (LAMBDA_EXPR_REGEN_INFO (lambda));
+      tree regen_args = lambda_regenerating_args (t);
       if (args)
-	args = add_to_template_args (outer_args, args);
+	args = add_to_template_args (regen_args, args);
       else
-	args = outer_args;
+	args = regen_args;
     }
 
   /* If any arguments depend on template parameters, we can't
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d71be0a5bc7..f09055e4852 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7742,6 +7742,7 @@ extern void finish_lambda_scope			(void);
 extern tree start_lambda_function		(tree fn, tree lambda_expr);
 extern void finish_lambda_function		(tree body);
 extern bool regenerated_lambda_fn_p		(tree);
+extern tree lambda_regenerating_args		(tree);
 extern tree most_general_lambda			(tree);
 extern tree finish_omp_target			(location_t, tree, tree, bool);
 extern void finish_omp_target_clauses		(location_t, tree, tree *);
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index c7af4712d8b..b58067d50e9 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -14446,6 +14446,21 @@ most_general_lambda (tree t)
   return t;
 }
 
+/* Return the set of template arguments used to regenerate the lambda T
+   from its most general lambda.  */
+
+tree
+lambda_regenerating_args (tree t)
+{
+  if (LAMBDA_FUNCTION_P (t))
+    t = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t));
+  gcc_assert (TREE_CODE (t) == LAMBDA_EXPR);
+  if (tree ti = LAMBDA_EXPR_REGEN_INFO (t))
+    return TI_ARGS (ti);
+  else
+    return NULL_TREE;
+}
+
 /* We're instantiating a variable from template function TCTX.  Return the
    corresponding current enclosing scope.  We can match them up using
    DECL_SOURCE_LOCATION because lambdas only ever have one source location, and
@@ -30127,12 +30142,24 @@ do_auto_deduction (tree type, tree init, tree auto_node,
 	    return type;
 	}
 
-      if ((context == adc_return_type
-	   || context == adc_variable_type
-	   || context == adc_decomp_type)
-	  && current_function_decl
-	  && DECL_TEMPLATE_INFO (current_function_decl))
-	outer_targs = DECL_TI_ARGS (current_function_decl);
+      if (context == adc_return_type
+	  || context == adc_variable_type
+	  || context == adc_decomp_type)
+	if (tree fn = current_function_decl)
+	  if (DECL_TEMPLATE_INFO (fn) || LAMBDA_FUNCTION_P (fn))
+	    {
+	      outer_targs = DECL_TEMPLATE_INFO (fn)
+		? DECL_TI_ARGS (fn) : NULL_TREE;
+	      if (LAMBDA_FUNCTION_P (fn))
+		{
+		  /* As in satisfy_declaration_constraints.  */
+		  tree regen_args = lambda_regenerating_args (fn);
+		  if (outer_targs)
+		    outer_targs = add_to_template_args (regen_args, outer_targs);
+		  else
+		    outer_targs = regen_args;
+		}
+	    }
 
       tree full_targs = add_to_template_args (outer_targs, targs);
 
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-lambda18.C b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda18.C
new file mode 100644
index 00000000000..f1058daf317
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-lambda18.C
@@ -0,0 +1,14 @@
+// PR c++/103706
+// { dg-do compile { target c++20 } }
+
+template<class T, class U> concept C = __is_same(U, int);
+
+template<class T> void f() {
+  []() -> C<T> auto {
+    C<T> auto x = T(); // { dg-error "constraints" }
+    return T(); // { dg-error "constraints" }
+  }();
+}
+
+template void f<int>(); // { dg-bogus "" }
+template void f<char>(); // { dg-message "required from here" }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-02-08 13:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-08 13:48 [gcc r12-7101] c++: constrained auto in lambda using outer tparms [PR103706] Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).