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.
@@ -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 \
@@ -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));
new file mode 100644
@@ -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);
+}