This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH for c++/52043 (ICE with pack expansion)


The problem here is with tsubst_pack_expansion trying to decide whether or not to look at local_specializations. Previously we checked cp_unevaluated_context, but that was wrong because some uses in trailing-return-types have the pack expansion outside the decltype. Then we checked at_function_scope_p(), but that turns out not to be right either, because we might be in a different function, or have already discarded local_specializations. This patch fixes the check to use whether we were in a function when we parsed the expansion, which is more stable.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 480a0ab1c458357a701b7ae604b88c058b22d237
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Jan 31 11:10:21 2012 -0500

    	PR c++/52043
    	* cp-tree.h (PACK_EXPANSION_LOCAL_P): New.
    	* pt.c (make_pack_expansion, tsubst_initializer_list): Set it.
    	(tsubst_pack_expansion): Check it.

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f27755e..d435dbd 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -76,6 +76,7 @@ c-common.h, not after.
       TRANSACTION_EXPR_IS_STMT (in TRANSACTION_EXPR)
       CONVERT_EXPR_VBASE_PATH (in CONVERT_EXPR)
       OVL_ARG_DEPENDENT (in OVERLOAD)
+      PACK_EXPANSION_LOCAL_P (in *_PACK_EXPANSION)
    1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
       TI_PENDING_TEMPLATE_FLAG.
       TEMPLATE_PARMS_FOR_INLINE.
@@ -2839,6 +2840,9 @@ extern void decl_shadowed_for_var_insert (tree, tree);
     ? &TYPE_MAXVAL (NODE)			\
     : &TREE_OPERAND ((NODE), 2))
 
+/* True iff this pack expansion is within a function context.  */
+#define PACK_EXPANSION_LOCAL_P(NODE) TREE_LANG_FLAG_0 (NODE)
+
 /* Determine if this is an argument pack.  */
 #define ARGUMENT_PACK_P(NODE)                          \
   (TREE_CODE (NODE) == TYPE_ARGUMENT_PACK              \
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ad2b4df..4c93b31 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3238,6 +3238,8 @@ make_pack_expansion (tree arg)
     }
   PACK_EXPANSION_PARAMETER_PACKS (result) = parameter_packs;
 
+  PACK_EXPANSION_LOCAL_P (result) = at_function_scope_p ();
+
   return result;
 }
 
@@ -9340,7 +9342,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain,
        }
       if (TREE_CODE (parm_pack) == PARM_DECL)
 	{
-	  if (at_function_scope_p ())
+	  if (PACK_EXPANSION_LOCAL_P (t))
 	    arg_pack = retrieve_local_specialization (parm_pack);
 	  else
 	    {
@@ -18905,6 +18907,7 @@ tsubst_initializer_list (tree t, tree argvec)
           /* Build a dummy EXPR_PACK_EXPANSION that will be used to
              expand each argument in the TREE_VALUE of t.  */
           expr = make_node (EXPR_PACK_EXPANSION);
+	  PACK_EXPANSION_LOCAL_P (expr) = true;
           PACK_EXPANSION_PARAMETER_PACKS (expr) =
             PACK_EXPANSION_PARAMETER_PACKS (TREE_PURPOSE (t));
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic122.C b/gcc/testsuite/g++.dg/cpp0x/variadic122.C
new file mode 100644
index 0000000..6a1fb08
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/variadic122.C
@@ -0,0 +1,22 @@
+// PR c++/52043
+// { dg-options "-std=c++11 -Wreturn-type" }
+
+template < class T > struct Container
+{
+  T f ();
+};
+
+template < class T >
+T deref (T)
+{}				// { dg-warning "no return" }
+
+template < class T, class ... Args >
+auto deref (T u, int, Args ... args)->decltype (deref (u.f (), args ...))
+{}				// { dg-warning "no return" }
+
+void 
+foo ()
+{
+  Container < Container < int > > v;
+  deref (v, 2);
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]