I discovered that we were pushing an OMP UDR in a template before
setting DECL_LOCAL_DECL.  This caused the template machinery to give
it some template info.  It doesn't need that, and this changes the
parser to set it earlier.  We have to adjust instantiate_body to not
try and access such a function's non-existant template_info.  The
access checks that we're no longer doing are the same as those we did
on the containing function anyway.  So nothing is lost.

        gcc/cp/
        * parser.c (cp_parser_omp_declare_reduction): Set
        DECL_LOCAL_DECL_P before push_template_decl.
        * pt.c (instantiate_body): Nested fns do not have template_info.

pushing to trunk

nathan
--
Nathan Sidwell
diff --git i/gcc/cp/parser.c w/gcc/cp/parser.c
index 03780fab0a7..52637b1d2af 100644
--- i/gcc/cp/parser.c
+++ w/gcc/cp/parser.c
@@ -42700,15 +42700,19 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
       DECL_ATTRIBUTES (fndecl)
 	= tree_cons (get_identifier ("gnu_inline"), NULL_TREE,
 		     DECL_ATTRIBUTES (fndecl));
-      if (processing_template_decl)
-	fndecl = push_template_decl (fndecl);
       bool block_scope = false;
-      tree block = NULL_TREE;
       if (current_function_decl)
 	{
 	  block_scope = true;
 	  DECL_CONTEXT (fndecl) = current_function_decl;
 	  DECL_LOCAL_DECL_P (fndecl) = true;
+	}
+
+      if (processing_template_decl)
+	fndecl = push_template_decl (fndecl);
+
+      if (block_scope)
+	{
 	  if (!processing_template_decl)
 	    pushdecl (fndecl);
 	}
@@ -42736,6 +42740,8 @@ cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
 	  /* We should never meet a matched duplicate decl.  */
 	  gcc_checking_assert (d == error_mark_node || d == fndecl);
 	}
+
+      tree block = NULL_TREE;
       if (!block_scope)
 	start_preparsed_function (fndecl, NULL_TREE, SF_PRE_PARSED);
       else
diff --git i/gcc/cp/pt.c w/gcc/cp/pt.c
index 0d2946fd7c4..fdeaa02c887 100644
--- i/gcc/cp/pt.c
+++ w/gcc/cp/pt.c
@@ -25595,9 +25595,11 @@ instantiate_body (tree pattern, tree args, tree d, bool nested_p)
       if (nested_p)
 	block = push_stmt_list ();
       else
-	start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
+	{
+	  start_preparsed_function (d, NULL_TREE, SF_PRE_PARSED);
 
-      perform_instantiation_time_access_checks (code_pattern, args);
+	  perform_instantiation_time_access_checks (code_pattern, args);
+	}
 
       /* Create substitution entries for the parameters.  */
       register_parameter_specializations (code_pattern, d);
@@ -25636,7 +25638,8 @@ instantiate_body (tree pattern, tree args, tree d, bool nested_p)
     }
 
   /* We're not deferring instantiation any more.  */
-  TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
+  if (!nested_p)
+    TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
 
   if (push_to_top)
     pop_from_top_level ();

Reply via email to