C++ PATCH for c++/80096, ICE with C++17 non-type auto

Submitted by Jason Merrill on March 20, 2017, 7:58 p.m.

Details

Message ID CADzB+2=4XrSaLj81pAWMY0hzRszyZ9pUPu7zt5WaKK1LQkizhg@mail.gmail.com
State New
Headers show

Commit Message

Jason Merrill March 20, 2017, 7:58 p.m.
Normally tsubst substitutes into the TREE_TYPE of the argument before
proceeding; that's wrong for an auto template parameter, which should
just get the appropriate type from its non-type argument.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 63a21767d094ac5c7b1a1ca0cd3d0366411c1a77
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Mar 20 15:36:49 2017 -0400

            PR c++/80096 - ICE with C++17 non-type auto.
    
            * pt.c (tsubst): Delay tsubst of type of template non-type
            parameter.

Patch hide | download patch | download mbox

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f180710..a4bf890 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -13388,6 +13388,7 @@  tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
   if (type
       && code != TYPENAME_TYPE
       && code != TEMPLATE_TYPE_PARM
+      && code != TEMPLATE_PARM_INDEX
       && code != IDENTIFIER_NODE
       && code != FUNCTION_TYPE
       && code != METHOD_TYPE)
@@ -13690,6 +13691,10 @@  tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	    break;
 
 	  case TEMPLATE_PARM_INDEX:
+	    /* OK, now substitute the type of the non-type parameter.  We
+	       couldn't do it earlier because it might be an auto parameter,
+	       and we wouldn't need to if we had an argument.  */
+	    type = tsubst (type, args, complain, in_decl);
 	    r = reduce_template_parm_level (t, type, levels, args, complain);
 	    break;
 
diff --git a/gcc/testsuite/g++.dg/cpp1z/nontype-auto10.C b/gcc/testsuite/g++.dg/cpp1z/nontype-auto10.C
new file mode 100644
index 0000000..381ed51
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nontype-auto10.C
@@ -0,0 +1,9 @@ 
+// PR c++/80096
+// { dg-options -std=c++1z }
+
+template<auto> struct A
+{
+  template<int> struct B {};
+};
+
+A<0> a;