re PR c++/51507 ([C++0x] Function parameter pack doesn't use in template-argument...
authorJason Merrill <jason@redhat.com>
Fri, 23 Dec 2011 22:00:13 +0000 (17:00 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Fri, 23 Dec 2011 22:00:13 +0000 (17:00 -0500)
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): Clear current_function_decl.

From-SVN: r182668

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/cp/search.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/variadic121.C [new file with mode: 0644]

index 10182fcdd1b2491c3e2d353af938263389eee20f..b025fa7e623847506f7633366a7042c03ca402a5 100644 (file)
@@ -1,5 +1,11 @@
 2011-12-23  Jason Merrill  <jason@redhat.com>
 
+       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.
 
index 820b1ff755240758a20cb95efb98d633e400a24f..20f67aa6edf0ad0774e1714c984b6513d90c4e78 100644 (file)
@@ -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;
 
index 0ceb5bc14f8d16abc0d3f820a047619cfeb305bf..45fdafc37237f7e4977aea4d28451a68dd740d7e 100644 (file)
@@ -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.  */
index dac74c38c67a47b48a9a65bc8d5d8a628ecada4f..c2ca72bfa16522f8cab4e138ddb17fdcfc75719f 100644 (file)
@@ -1,3 +1,8 @@
+2011-12-23  Jason Merrill  <jason@redhat.com>
+
+       PR c++/51507
+       * g++.dg/cpp0x/variadic121.C: New.
+
 2011-12-23  Uros Bizjak  <ubizjak@gmail.com>
 
        * 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 (file)
index 0000000..805c006
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/51507
+// { dg-options -std=c++0x }
+
+template<typename ...>
+struct foo { typedef void type; };
+template<typename ...Ts>
+auto g(Ts ...ts)->
+  typename foo<decltype(ts)...>::type
+{}
+int main() {
+  g(42);
+}