commit 190aed44d9e0fcbf89cedddcc2003b41a0899374
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Jun 14 21:56:33 2018 -0400

            * pt.c (tsubst_default_argument): Use push_to/pop_from_top_level.
    
            * name-lookup.c (do_pushtag): Don't look through complete types, but
            don't add to them either.  Get context from current_binding_level.

diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 7990029d70c..ec001016d3e 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -6521,12 +6521,7 @@ do_pushtag (tree name, tree type, tag_scope scope)
 	 || (b->kind == sk_template_parms
 	     && (b->explicit_spec_p || scope == ts_global))
 	 || (b->kind == sk_class
-	     && (scope != ts_current
-		 /* We may be defining a new type in the initializer
-		    of a static member variable. We allow this when
-		    not pedantic, and it is particularly useful for
-		    type punning via an anonymous union.  */
-		 || COMPLETE_TYPE_P (b->this_entity))))
+	     && scope != ts_current))
     b = b->level_chain;
 
   gcc_assert (identifier_p (name));
@@ -6540,15 +6535,18 @@ do_pushtag (tree name, tree type, tag_scope scope)
 
       if (! context)
 	{
-	  tree cs = current_scope ();
+	  cp_binding_level *cb = b;
+	  while (cb->kind != sk_namespace
+		 && cb->kind != sk_class
+		 && (cb->kind != sk_function_parms
+		     || !cb->this_entity))
+	    cb = cb->level_chain;
+	  tree cs = cb->this_entity;
 
-	  /* Avoid setting the lambda context to a current_function_decl that
-	     we aren't actually inside, e.g. one set by push_access_scope
-	     during tsubst_default_argument.  */
-	  if (cs && TREE_CODE (cs) == FUNCTION_DECL
-	      && LAMBDA_TYPE_P (type)
-	      && !at_function_scope_p ())
-	    cs = DECL_CONTEXT (cs);
+	  gcc_checking_assert (TREE_CODE (cs) == FUNCTION_DECL
+			       ? cs == current_function_decl
+			       : TYPE_P (cs) ? cs == current_class_type
+			       : cs == current_namespace);
 
 	  if (scope == ts_current
 	      || (cs && TREE_CODE (cs) == FUNCTION_DECL))
@@ -6587,11 +6585,11 @@ do_pushtag (tree name, tree type, tag_scope scope)
 
       if (b->kind == sk_class)
 	{
-	  if (!TYPE_BEING_DEFINED (current_class_type)
-	      && !LAMBDA_TYPE_P (type))
-	    return error_mark_node;
-
-	  if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
+	  if (!TYPE_BEING_DEFINED (current_class_type))
+	    /* Don't push anywhere if the class is complete; a lambda in an
+	       NSDMI is not a member of the class.  */
+	    ;
+	  else if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
 	    /* Put this TYPE_DECL on the TYPE_FIELDS list for the
 	       class.  But if it's a member template class, we want
 	       the TEMPLATE_DECL, not the TYPE_DECL, so this is done
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index ed634ddeefb..4ee84b201e9 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12675,8 +12675,6 @@ tree
 tsubst_default_argument (tree fn, int parmnum, tree type, tree arg,
 			 tsubst_flags_t complain)
 {
-  tree saved_class_ptr = NULL_TREE;
-  tree saved_class_ref = NULL_TREE;
   int errs = errorcount + sorrycount;
 
   /* This can happen in invalid code.  */
@@ -12709,19 +12707,10 @@ tsubst_default_argument (tree fn, int parmnum, tree type, tree arg,
 
      we must be careful to do name lookup in the scope of S<T>,
      rather than in the current class.  */
+  push_to_top_level ();
   push_access_scope (fn);
-  /* The "this" pointer is not valid in a default argument.  */
-  if (cfun)
-    {
-      saved_class_ptr = current_class_ptr;
-      cp_function_chain->x_current_class_ptr = NULL_TREE;
-      saved_class_ref = current_class_ref;
-      cp_function_chain->x_current_class_ref = NULL_TREE;
-    }
-
   start_lambda_scope (parm);
 
-  push_deferring_access_checks(dk_no_deferred);
   /* The default argument expression may cause implicitly defined
      member functions to be synthesized, which will result in garbage
      collection.  We must treat this situation as if we were within
@@ -12732,17 +12721,9 @@ tsubst_default_argument (tree fn, int parmnum, tree type, tree arg,
 		     complain, NULL_TREE,
 		     /*integral_constant_expression_p=*/false);
   --function_depth;
-  pop_deferring_access_checks();
 
   finish_lambda_scope ();
 
-  /* Restore the "this" pointer.  */
-  if (cfun)
-    {
-      cp_function_chain->x_current_class_ptr = saved_class_ptr;
-      cp_function_chain->x_current_class_ref = saved_class_ref;
-    }
-
   if (errorcount+sorrycount > errs
       && (complain & tf_warning_or_error))
     inform (input_location,
@@ -12752,6 +12733,7 @@ tsubst_default_argument (tree fn, int parmnum, tree type, tree arg,
   arg = check_default_argument (type, arg, complain);
 
   pop_access_scope (fn);
+  pop_from_top_level ();
 
   if (arg != error_mark_node && !cp_unevaluated_operand)
     {
diff --git a/gcc/testsuite/g++.dg/template/crash108.C b/gcc/testsuite/g++.dg/template/crash108.C
index 9bcabc6009b..3ffadc14c25 100644
--- a/gcc/testsuite/g++.dg/template/crash108.C
+++ b/gcc/testsuite/g++.dg/template/crash108.C
@@ -1,5 +1,5 @@
 // PR c++/50861
 
-template<class T> struct A {A(int b=k(0));}; // { dg-error "parameter|argument" }
-void f(int k){A<int> a;} // // { dg-message "declared" }
-// { dg-message "note" "note" { target *-*-* } 3 }
+template<class T> struct A {A(int b=k(0));}; // { dg-error "not declared" }
+ // { dg-error "that depend on a template parameter" "" { target *-*-* } .-1 }
+void f(int k){A<int> a;}
