Patchwork [C++,Patch/RFC] PR 57092

login
register
mail settings
Submitter Paolo Carlini
Date April 30, 2013, 4:52 p.m.
Message ID <517FF6DF.9020706@oracle.com>
Download mbox | patch
Permalink /patch/240665/
State New
Headers show

Comments

Paolo Carlini - April 30, 2013, 4:52 p.m.
... 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.

///////////////////

Patch

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;