[gcc(refs/vendors/ARM/heads/arm-perf-staging)] c++ ICE with nested requirement as default tpl parm[PR94827]

Tamar Christina tnfchris@gcc.gnu.org
Fri Jul 17 15:07:19 GMT 2020


https://gcc.gnu.org/g:c416c52bcdb120db5e8c53a51bd78c4360daf79b

commit c416c52bcdb120db5e8c53a51bd78c4360daf79b
Author: Nathan Sidwell <nathan@acm.org>
Date:   Thu Apr 30 08:23:16 2020 -0700

    c++ ICE with nested requirement as default tpl parm[PR94827]
    
    Template headers are not incrementally updated as we parse its parameters.
    We maintain a dummy level until the closing > when we replace the dummy with
    a real parameter set.  requires processing was expecting a properly populated
    arg_vec in current_template_parms, and then creates a self-mapping of parameters
    from that.  But we don't need to do that, just teach map_arguments to look at
    TREE_VALUE when args is NULL.
    
            * constraint.cc (map_arguments): If ARGS is null, it's a
            self-mapping of parms.
            (finish_nested_requirement): Do not pass argified
            current_template_parms to normalization.
            (tsubst_nested_requirement): Don't assert no template parms.

Diff:
---
 gcc/cp/ChangeLog                        | 10 ++++++++++
 gcc/cp/constraint.cc                    | 27 ++++++++++++++++-----------
 gcc/testsuite/g++.dg/concepts/pr94827.C | 15 +++++++++++++++
 3 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1fa0e123cb1..3c57945cecf 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2020-04-30  Jason Merrill  <jason@redhat.com>
+	    Nathan Sidwell  <nathan@acm.org>
+
+	PR c++/94827
+	* constraint.cc (map_arguments): If ARGS is null, it's a
+	self-mapping of parms.
+	(finish_nested_requirement): Do not pass argified
+	current_template_parms to normalization.
+	(tsubst_nested_requirement): Don't assert no template parms.
+
 2020-04-30  Iain Sandoe  <iain@sandoe.co.uk>
 
 	PR c++/94886
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 866b0f51b05..85513fecf43 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -546,12 +546,16 @@ static tree
 map_arguments (tree parms, tree args)
 {
   for (tree p = parms; p; p = TREE_CHAIN (p))
-    {
-      int level;
-      int index;
-      template_parm_level_and_index (TREE_VALUE (p), &level, &index);
-      TREE_PURPOSE (p) = TMPL_ARG (args, level, index);
-    }
+    if (args)
+      {
+	int level;
+	int index;
+	template_parm_level_and_index (TREE_VALUE (p), &level, &index);
+	TREE_PURPOSE (p) = TMPL_ARG (args, level, index);
+      }
+    else
+      TREE_PURPOSE (p) = TREE_VALUE (p);
+
   return parms;
 }
 
@@ -2005,8 +2009,6 @@ tsubst_compound_requirement (tree t, tree args, subst_info info)
 static tree
 tsubst_nested_requirement (tree t, tree args, subst_info info)
 {
-  gcc_assert (!uses_template_parms (args));
-
   /* Ensure that we're in an evaluation context prior to satisfaction.  */
   tree norm = TREE_VALUE (TREE_TYPE (t));
   tree result = satisfy_constraint (norm, args, info);
@@ -2953,12 +2955,15 @@ finish_compound_requirement (location_t loc, tree expr, tree type, bool noexcept
 tree
 finish_nested_requirement (location_t loc, tree expr)
 {
+  /* Currently open template headers have dummy arg vectors, so don't
+     pass into normalization.  */
+  tree norm = normalize_constraint_expression (expr, NULL_TREE, false);
+  tree args = current_template_parms
+    ? template_parms_to_args (current_template_parms) : NULL_TREE;
+
   /* Save the normalized constraint and complete set of normalization
      arguments with the requirement.  We keep the complete set of arguments
      around for re-normalization during diagnostics.  */
-  tree args = current_template_parms
-    ? template_parms_to_args (current_template_parms) : NULL_TREE;
-  tree norm = normalize_constraint_expression (expr, args, false);
   tree info = build_tree_list (args, norm);
 
   /* Build the constraint, saving its normalization as its type.  */
diff --git a/gcc/testsuite/g++.dg/concepts/pr94827.C b/gcc/testsuite/g++.dg/concepts/pr94827.C
new file mode 100644
index 00000000000..f14ec2551a1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/pr94827.C
@@ -0,0 +1,15 @@
+// PR 94287 ICE looking inside open template-parm level
+// { dg-do run { target c++17 } }
+// { dg-options -fconcepts }
+
+template <typename T,
+  bool X = requires { requires (sizeof(T)==1); } >
+  int foo(T) { return X; }
+
+int main() {
+  if (!foo('4'))
+    return 1;
+  if (foo (4))
+    return 2;
+  return 0;
+}


More information about the Gcc-cvs mailing list