... sorry about the latter confabulations ;) I went almost crazy trying to avoid the copy_node, but in this case it seems really necessary. The below appears to regtest fine (already beyond g++.dg/dg.exp).

Thanks,
Paolo.

///////////////////
Index: cp/pt.c
===================================================================
--- cp/pt.c     (revision 198461)
+++ cp/pt.c     (working copy)
@@ -11781,14 +11781,23 @@ tsubst (tree t, tree args, tsubst_flags_t complain
     case DECLTYPE_TYPE:
       {
        tree type;
+       tree expr = DECLTYPE_TYPE_EXPR (t);
+       bool id = DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t);
 
        ++cp_unevaluated_operand;
        ++c_inhibit_evaluation_warnings;
 
-       type = tsubst_copy_and_build (DECLTYPE_TYPE_EXPR (t), args,
-                                     complain|tf_decltype, in_decl,
-                                     /*function_p*/false,
-                                     /*integral_constant_expression*/false);
+       if (id && TREE_CODE (expr) == TEMPLATE_PARM_INDEX)
+         {
+           type = copy_node (expr);
+           TREE_TYPE (type) = tsubst (TREE_TYPE (expr), args,
+                                      complain|tf_decltype, in_decl);
+         }
+       else
+         type = tsubst_copy_and_build (expr, args,
+                                       complain|tf_decltype, in_decl,
+                                       /*function_p*/false,
+                                       /*integral_constant_expression*/false);
 
        --cp_unevaluated_operand;
        --c_inhibit_evaluation_warnings;
@@ -11800,8 +11809,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain
          type = lambda_proxy_type (type);
        else
          {
-           bool id = DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t);
-           if (id && TREE_CODE (DECLTYPE_TYPE_EXPR (t)) == BIT_NOT_EXPR
+           if (id && TREE_CODE (expr) == BIT_NOT_EXPR
                && EXPR_P (type))
              /* In a template ~id could be either a complement expression
                 or an unqualified-id naming a destructor; if instantiating
Index: testsuite/g++.dg/cpp0x/decltype53.C
===================================================================
--- testsuite/g++.dg/cpp0x/decltype53.C (revision 0)
+++ testsuite/g++.dg/cpp0x/decltype53.C (working copy)
@@ -0,0 +1,11 @@
+// PR c++/57092
+// { dg-do compile { target c++11 } }
+
+template <void (*F)(int)>
+class B {
+  decltype(F) v;
+};
+
+void foo(int) {}
+
+B<foo> o;

Reply via email to