From: Jason Merrill Date: Wed, 26 May 2010 15:00:02 +0000 (-0400) Subject: re PR c++/43382 ([C++0x] ICE with auto return type and variadic templates) X-Git-Tag: upstream/12.2.0~92876 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1dba29f845a7dfa3f87bc9fb7040648b3cd68082;p=platform%2Fupstream%2Fgcc.git re PR c++/43382 ([C++0x] ICE with auto return type and variadic templates) PR c++/43382 * pt.c (fn_type_unification): Don't get confused by recursive unification. From-SVN: r159873 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ff3bc5f..3ad1aaf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2010-05-26 Jason Merrill + + PR c++/43382 + * pt.c (fn_type_unification): Don't get confused by recursive + unification. + 2010-05-26 Steven Bosscher * cp-lang.c: Do not include expr.h. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6c9f31d..fd34d9f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8251,7 +8251,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, int i, len = -1; tree result; int incomplete = 0; - bool very_local_specializations = false; + htab_t saved_local_specializations = NULL; gcc_assert (PACK_EXPANSION_P (t)); pattern = PACK_EXPANSION_PATTERN (t); @@ -8269,13 +8269,15 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (TREE_CODE (parm_pack) == PARM_DECL) { - arg_pack = retrieve_local_specialization (parm_pack); - if (arg_pack == NULL_TREE) + if (!cp_unevaluated_operand) + arg_pack = retrieve_local_specialization (parm_pack); + else { - /* This can happen for a parameter name used later in a function - declaration (such as in a late-specified return type). Just - make a dummy decl, since it's only used for its type. */ - gcc_assert (cp_unevaluated_operand != 0); + /* We can't rely on local_specializations for a parameter + name used later in a function declaration (such as in a + late-specified return type). Even if it exists, it might + have the wrong value for a recursive call. Just make a + dummy decl, since it's only used for its type. */ arg_pack = tsubst_decl (parm_pack, args, complain); arg_pack = make_fnparm_pack (arg_pack); } @@ -8381,11 +8383,13 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (len < 0) return error_mark_node; - if (!local_specializations) + if (cp_unevaluated_operand) { - /* We're in a late-specified return type, so we don't have a local - specializations table. Create one for doing this expansion. */ - very_local_specializations = true; + /* We're in a late-specified return type, so create our own local + specializations table; the current table is either NULL or (in the + case of recursive unification) might have bindings that we don't + want to use or alter. */ + saved_local_specializations = local_specializations; local_specializations = htab_create (37, hash_local_specialization, eq_local_specializations, @@ -8476,10 +8480,10 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, } } - if (very_local_specializations) + if (saved_local_specializations) { htab_delete (local_specializations); - local_specializations = NULL; + local_specializations = saved_local_specializations; } return result; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a319f63..a163beb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-05-26 Jason Merrill + + PR c++/43382 + * g++.dg/cpp0x/variadic101.C: New. + 2010-05-26 Richard Guenther PR rtl-optimization/44164 diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic101.C b/gcc/testsuite/g++.dg/cpp0x/variadic101.C new file mode 100644 index 0000000..445a770 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic101.C @@ -0,0 +1,23 @@ +// PR c++/43382 +// { dg-options "-std=c++0x" } + +template +struct Container +{ T f() const; }; + +template +T deref(const T& t) +{ return t; } + + +template +auto +deref(const T& u, int r, Args... args) +-> decltype(deref(u.f(), args...)) +{ return deref(u.f(), args...); } + +int main(void) +{ + Container> v; + deref(v,1,2); +}