diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 10182fcdd1b..b025fa7e623 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2011-12-23 Jason Merrill + PR c++/51507 + * search.c (at_function_scope_p): Also check cfun. + * pt.c (tsubst_pack_expansion): Check it instead of + cp_unevaluated_operand. + (instantiate_template_1): Use push_to_top_level. + * tree.c (dependent_name): OFFSET_REF and BASELINK are not dependent names. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 820b1ff7552..20f67aa6edf 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9297,6 +9297,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, int i, len = -1; tree result; htab_t saved_local_specializations = NULL; + bool need_local_specializations = false; int levels; gcc_assert (PACK_EXPANSION_P (t)); @@ -9330,7 +9331,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, } if (TREE_CODE (parm_pack) == PARM_DECL) { - if (!cp_unevaluated_operand) + if (at_function_scope_p ()) arg_pack = retrieve_local_specialization (parm_pack); else { @@ -9346,6 +9347,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, arg_pack = NULL_TREE; else arg_pack = make_fnparm_pack (arg_pack); + need_local_specializations = true; } } else @@ -9476,7 +9478,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, if (len < 0) return error_mark_node; - if (cp_unevaluated_operand) + if (need_local_specializations) { /* We're in a late-specified return type, so create our own local specializations table; the current table is either NULL or (in the @@ -14524,7 +14526,6 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) tree fndecl; tree gen_tmpl; tree spec; - HOST_WIDE_INT saved_processing_template_decl; if (tmpl == error_mark_node) return error_mark_node; @@ -14585,18 +14586,22 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) deferring all checks until we have the FUNCTION_DECL. */ push_deferring_access_checks (dk_deferred); - /* Although PROCESSING_TEMPLATE_DECL may be true at this point - (because, for example, we have encountered a non-dependent - function call in the body of a template function and must now - determine which of several overloaded functions will be called), - within the instantiation itself we are not processing a - template. */ - saved_processing_template_decl = processing_template_decl; - processing_template_decl = 0; + /* Instantiation of the function happens in the context of the function + template, not the context of the overload resolution we're doing. */ + push_to_top_level (); + if (DECL_CLASS_SCOPE_P (gen_tmpl)) + { + tree ctx = tsubst (DECL_CONTEXT (gen_tmpl), targ_ptr, + complain, gen_tmpl); + push_nested_class (ctx); + } /* Substitute template parameters to obtain the specialization. */ fndecl = tsubst (DECL_TEMPLATE_RESULT (gen_tmpl), targ_ptr, complain, gen_tmpl); - processing_template_decl = saved_processing_template_decl; + if (DECL_CLASS_SCOPE_P (gen_tmpl)) + pop_nested_class (); + pop_from_top_level (); + if (fndecl == error_mark_node) return error_mark_node; diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 0ceb5bc14f8..45fdafc3723 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -539,7 +539,11 @@ int at_function_scope_p (void) { tree cs = current_scope (); - return cs && TREE_CODE (cs) == FUNCTION_DECL; + /* Also check cfun to make sure that we're really compiling + this function (as opposed to having set current_function_decl + for access checking or some such). */ + return (cs && TREE_CODE (cs) == FUNCTION_DECL + && cfun && cfun->decl == current_function_decl); } /* Returns true if the innermost active scope is a class scope. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dac74c38c67..c2ca72bfa16 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-12-23 Jason Merrill + + PR c++/51507 + * g++.dg/cpp0x/variadic121.C: New. + 2011-12-23 Uros Bizjak * gcc.dg/vect/fast-math-pr35982.c: Fix parenthesis in target selectors. diff --git a/gcc/testsuite/g++.dg/cpp0x/variadic121.C b/gcc/testsuite/g++.dg/cpp0x/variadic121.C new file mode 100644 index 00000000000..805c0065fe9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/variadic121.C @@ -0,0 +1,12 @@ +// PR c++/51507 +// { dg-options -std=c++0x } + +template +struct foo { typedef void type; }; +template +auto g(Ts ...ts)-> + typename foo::type +{} +int main() { + g(42); +}