C++ PATCH for c++/82664, infinite recursion with ref-to-fn non-type parameter

Message ID CADzB+2==V2WTDTCNRJJpf55XR-KhrJtAXz6SkKp+ieEw=kqNMQ@mail.gmail.com
State New
Headers show
Series
  • C++ PATCH for c++/82664, infinite recursion with ref-to-fn non-type parameter
Related show

Commit Message

Jason Merrill Feb. 16, 2018, 7:05 p.m.
The use_partial_inst_tmpl code in lookup_template_class didn't work as
intended because when converting the ref-to-fn parameter to the same
type we wrapped it in a couple of extra NOP_EXPR.

Tested x86_64-pc-linux-gnu, applying to trunk and 7.
commit ac1c39476b98ab4b6b52952df5baa07cf923d4e0
Author: Jason Merrill <jason@redhat.com>
Date:   Fri Feb 16 13:34:24 2018 -0500

            PR c++/82664 - ICE with reference to function template parm.
    
            * pt.c (convert_nontype_argument_function): Avoid obfuscationg
            NOP_EXPRs.

Patch

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 268cfe5a454..89790717eca 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6143,7 +6143,12 @@  convert_nontype_argument_function (tree type, tree expr,
 
  accept:
   if (TREE_CODE (type) == REFERENCE_TYPE)
-    fn = build_address (fn);
+    {
+      if (REFERENCE_REF_P (fn))
+	fn = TREE_OPERAND (fn, 0);
+      else
+	fn = build_address (fn);
+    }
   if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (fn)))
     fn = build_nop (type, fn);
 
diff --git a/gcc/testsuite/g++.dg/template/nontype-fn1.C b/gcc/testsuite/g++.dg/template/nontype-fn1.C
new file mode 100644
index 00000000000..12d29a91a54
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/nontype-fn1.C
@@ -0,0 +1,11 @@ 
+// PR c++/82664
+
+template < typename > struct target_disambiguator;
+template < typename R, typename A1 > struct target_disambiguator< R(A1) > {
+  typedef A1 type;
+  template < R (&)() > struct layout;
+};
+
+int main() {
+  typedef target_disambiguator< void (int) > ::type target_type ;
+}