This patch fixes the ICE in check-local-shadow, but reverts behaviour to the earlier ICE in pop_local_binding.

Check local shadow had a check when finding an outer local scope for function_parm_scope. But that code didn't make sense and was unreachable with the current testsuite. So I removed it. However, this testcase needed it.

It needed it because do_pushdecl_with_scope clears current_function_decl, even if the scope being pushed into happens to be the same function. And in all uses cases, we're either pushing into a namespace scope (so it should be cleared) or pushig into a class scope (so it should be unchanged).

The code in pushtag that does this looks funky. I don;t think we do the same when pushing non-tags, and that's weird. Probably related to the older ICE in pop_local_binding. That happens because we're popping the VAR_DECL for 'e' but find the TYPE_DECL -- somethings getting the ordering wrong. I was unable to find a testcase that triggered the new ice without also triggering the old ice.

I'm leaving the bug open, but with a simpler testcase. At least the regression is fixed.

nathan

--
Nathan Sidwell
2018-03-09  Nathan Sidwell  <nat...@acm.org>

	PR c++/84733
	* name-lookup.c (do_pushdecl_with_scope): Only clear
	current_function_decl when pushing a non-class (i.e. namespace)
	scope.

Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 258338)
+++ cp/name-lookup.c	(working copy)
@@ -3965,9 +3965,7 @@ static tree
 do_pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend)
 {
   cp_binding_level *b;
-  tree function_decl = current_function_decl;
 
-  current_function_decl = NULL_TREE;
   if (level->kind == sk_class)
     {
       b = class_binding_level;
@@ -3977,12 +3975,15 @@ do_pushdecl_with_scope (tree x, cp_bindi
     }
   else
     {
+      tree function_decl = current_function_decl;
+      if (level->kind == sk_namespace)
+	current_function_decl = NULL_TREE;
       b = current_binding_level;
       current_binding_level = level;
       x = pushdecl (x, is_friend);
       current_binding_level = b;
+      current_function_decl = function_decl;
     }
-  current_function_decl = function_decl;
   return x;
 }
 

Reply via email to