... 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;