In this testcase, we were crashing because we decided that the int&& template parameter wasn't a valid argument for itself, which is wrong. It's unclear to me that it is ever possible to instantiate a template taking an rvalue ref parameter, but I guess we might as well handle it properly.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 78c6cbb0e9fb5796825dc49891c7921e9270c09e Author: Jason Merrill <ja...@redhat.com> Date: Tue Mar 13 14:25:00 2018 -0400 PR c++/84720 - ICE with rvalue ref non-type argument. * pt.c (convert_nontype_argument): Handle rvalue references. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fdc1c9a7a75..a16aef6bf58 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6932,11 +6932,18 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) return NULL_TREE; } - if (!lvalue_p (expr)) + if (!glvalue_p (expr) + || TYPE_REF_IS_RVALUE (type) != xvalue_p (expr)) { if (complain & tf_error) - error ("%qE is not a valid template argument for type %qT " - "because it is not an lvalue", expr, type); + { + if (TYPE_REF_IS_RVALUE (type)) + error ("%qE is not a valid template argument for type %qT " + "because it is not an xvalue", expr, type); + else + error ("%qE is not a valid template argument for type %qT " + "because it is not an lvalue", expr, type); + } return NULL_TREE; } diff --git a/gcc/testsuite/g++.dg/cpp0x/rv-targ1.C b/gcc/testsuite/g++.dg/cpp0x/rv-targ1.C new file mode 100644 index 00000000000..b8e0daba0f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/rv-targ1.C @@ -0,0 +1,10 @@ +// PR c++/84720 +// { dg-do compile { target c++11 } } + +template<int &&> +struct a { + template<typename...> + static void b() { + b(); + } +};