diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index f7f9297..c446057 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -9007,6 +9007,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
       if (! (complain & tf_error))
 	return error_mark_node;
 
+      basetype = DECL_CONTEXT (fn);
       name = constructor_name (basetype);
       if (permerror (input_location,
 		     "cannot call constructor %<%T::%D%> directly",
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 4747a72..9ba3df1 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -590,7 +590,11 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
   /* Add it to the appropriate closure class if we've started it.  */
   if (current_class_type
       && current_class_type == LAMBDA_EXPR_CLOSURE (lambda))
-    finish_member_declaration (member);
+    {
+      if (COMPLETE_TYPE_P (current_class_type))
+	internal_error ("trying to capture %qD after closure is complete", id);
+      finish_member_declaration (member);
+    }
 
   tree listmem = member;
   if (variadic)
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index a87f97f..ce7c0c5 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -3015,6 +3015,7 @@ write_expression (tree expr)
 	{
 	  scope = TREE_OPERAND (expr, 0);
 	  member = TREE_OPERAND (expr, 1);
+	  gcc_assert (!BASELINK_P (member));
 	}
       else
 	{
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d0d71fa..47d91bf 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7446,11 +7446,14 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
 	      /* In a template, be permissive by treating an object expression
 		 of incomplete type as dependent (after a pedwarn).  */
 	      diagnostic_t kind = (processing_template_decl
+				   && MAYBE_CLASS_TYPE_P (scope)
 				   ? DK_PEDWARN
 				   : DK_ERROR);
 	      cxx_incomplete_type_diagnostic
 		(location_of (postfix_expression),
 		 postfix_expression, scope, kind);
+	      if (!MAYBE_CLASS_TYPE_P (scope))
+		return error_mark_node;
 	      if (processing_template_decl)
 		{
 		  dependent_p = true;
@@ -20671,33 +20674,6 @@ parsing_nsdmi (void)
   return false;
 }
 
-/* Return true iff our current scope is a default capturing generic lambda
-   defined within a template.  FIXME: This is part of a workaround (see
-   semantics.c) to handle building lambda closure types correctly in templates
-   which we ultimately want to defer to instantiation time. */
-
-bool
-parsing_default_capturing_generic_lambda_in_template (void)
-{
-  if (!processing_template_decl || !current_class_type)
-    return false;
-
-  tree lam = CLASSTYPE_LAMBDA_EXPR (current_class_type);
-  if (!lam || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lam) == CPLD_NONE)
-    return false;
-
-  tree callop = lambda_function (lam);
-  if (!callop)
-    return false;
-
-  return (DECL_TEMPLATE_INFO (callop)
-	  && (DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (callop)) == callop)
-	  && ((current_nonlambda_class_type ()
-	       && CLASSTYPE_TEMPLATE_INFO (current_nonlambda_class_type ()))
-	      || ((current_nonlambda_function ()
-		   && DECL_TEMPLATE_INFO (current_nonlambda_function ())))));
-}
-
 /* Parse a late-specified return type, if any.  This is not a separate
    non-terminal, but part of a function declarator, which looks like
 
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 8f28221..b2e58d2 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2035,7 +2035,7 @@ finish_qualified_id_expr (tree qualifying_class,
 					    qualifying_class);
       pop_deferring_access_checks ();
     }
-  else if (BASELINK_P (expr) && !processing_template_decl)
+  else if (BASELINK_P (expr))
     {
       /* See if any of the functions are non-static members.  */
       /* If so, the expression may be relative to 'this'.  */
@@ -2055,8 +2055,6 @@ finish_qualified_id_expr (tree qualifying_class,
 	expr = build_offset_ref (qualifying_class, expr, /*address_p=*/false,
 				 complain);
     }
-  else if (BASELINK_P (expr))
-    ;
   else
     {
       /* In a template, return a SCOPE_REF for most qualified-ids
@@ -2065,7 +2063,8 @@ finish_qualified_id_expr (tree qualifying_class,
 	 know we have access and building up the SCOPE_REF confuses
 	 non-type template argument handling.  */
       if (processing_template_decl
-	  && !currently_open_class (qualifying_class))
+	  && (!currently_open_class (qualifying_class)
+	      || TREE_CODE (expr) == BIT_NOT_EXPR))
 	expr = build_qualified_name (TREE_TYPE (expr),
 				     qualifying_class, expr,
 				     template_p);
@@ -3595,78 +3594,12 @@ finish_id_expression (tree id_expression,
 		    ? CP_ID_KIND_UNQUALIFIED_DEPENDENT
 		    : CP_ID_KIND_UNQUALIFIED)));
 
-      /* If the name was dependent on a template parameter and we're not in a
-	 default capturing generic lambda within a template, we will resolve the
-	 name at instantiation time.  FIXME: For lambdas, we should defer
-	 building the closure type until instantiation time then we won't need
-	 the extra test here.  */
       if (dependent_p
-	  && !parsing_default_capturing_generic_lambda_in_template ())
-	{
-	  if (DECL_P (decl)
-	      && any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl)))
-	    /* Dependent type attributes on the decl mean that the TREE_TYPE is
-	       wrong, so just return the identifier.  */
-	    return id_expression;
-
-	  /* If we found a variable, then name lookup during the
-	     instantiation will always resolve to the same VAR_DECL
-	     (or an instantiation thereof).  */
-	  if (VAR_P (decl)
-	      || TREE_CODE (decl) == CONST_DECL
-	      || TREE_CODE (decl) == PARM_DECL)
-	    {
-	      mark_used (decl);
-	      return convert_from_reference (decl);
-	    }
-
-	  /* Create a SCOPE_REF for qualified names, if the scope is
-	     dependent.  */
-	  if (scope)
-	    {
-	      if (TYPE_P (scope))
-		{
-		  if (address_p && done)
-		    decl = finish_qualified_id_expr (scope, decl,
-						     done, address_p,
-						     template_p,
-						     template_arg_p,
-						     tf_warning_or_error);
-		  else
-		    {
-		      tree type = NULL_TREE;
-		      if (DECL_P (decl) && !dependent_scope_p (scope))
-			type = TREE_TYPE (decl);
-		      decl = build_qualified_name (type,
-						   scope,
-						   id_expression,
-						   template_p);
-		    }
-		}
-	      if (TREE_TYPE (decl))
-		decl = convert_from_reference (decl);
-	      return decl;
-	    }
-	  /* A TEMPLATE_ID already contains all the information we
-	     need.  */
-	  if (TREE_CODE (id_expression) == TEMPLATE_ID_EXPR)
-	    return id_expression;
-	  /* The same is true for FIELD_DECL, but we also need to
-	     make sure that the syntax is correct.  */
-	  else if (TREE_CODE (decl) == FIELD_DECL)
-	    {
-	      /* Since SCOPE is NULL here, this is an unqualified name.
-		 Access checking has been performed during name lookup
-		 already.  Turn off checking to avoid duplicate errors.  */
-	      push_deferring_access_checks (dk_no_check);
-	      decl = finish_non_static_data_member
-		       (decl, NULL_TREE,
-			/*qualifying_scope=*/NULL_TREE);
-	      pop_deferring_access_checks ();
-	      return decl;
-	    }
-	  return id_expression;
-	}
+	  && DECL_P (decl)
+	  && any_dependent_type_attributes_p (DECL_ATTRIBUTES (decl)))
+	/* Dependent type attributes on the decl mean that the TREE_TYPE is
+	   wrong, so just return the identifier.  */
+	return id_expression;
 
       if (TREE_CODE (decl) == NAMESPACE_DECL)
 	{
@@ -3700,6 +3633,7 @@ finish_id_expression (tree id_expression,
 	 expression.  Template parameters have already
 	 been handled above.  */
       if (! error_operand_p (decl)
+	  && !dependent_p
 	  && integral_constant_expression_p
 	  && ! decl_constant_var_p (decl)
 	  && TREE_CODE (decl) != CONST_DECL
@@ -3726,6 +3660,7 @@ finish_id_expression (tree id_expression,
 	  decl = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
 	}
       else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
+	       && !dependent_p
 	       && variable_template_p (TREE_OPERAND (decl, 0)))
 	{
 	  decl = finish_template_variable (decl);
@@ -3734,6 +3669,12 @@ finish_id_expression (tree id_expression,
 	}
       else if (scope)
 	{
+	  if (TREE_CODE (decl) == SCOPE_REF)
+	    {
+	      gcc_assert (same_type_p (scope, TREE_OPERAND (decl, 0)));
+	      decl = TREE_OPERAND (decl, 1);
+	    }
+
 	  decl = (adjust_result_of_qualified_name_lookup
 		  (decl, scope, current_nonlambda_class_type()));
 
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index dbac7f3..aab92d5 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2028,6 +2028,7 @@ build_qualified_name (tree type, tree scope, tree name, bool template_p)
       || scope == error_mark_node
       || name == error_mark_node)
     return error_mark_node;
+  gcc_assert (TREE_CODE (name) != SCOPE_REF);
   t = build2 (SCOPE_REF, type, scope, name);
   QUALIFIED_NAME_IS_TEMPLATE (t) = template_p;
   PTRMEM_OK_P (t) = true;
@@ -4663,6 +4664,8 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
       break;
 
     case BASELINK:
+      if (BASELINK_QUALIFIED_P (*tp))
+	WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (*tp)));
       WALK_SUBTREE (BASELINK_FUNCTIONS (*tp));
       *walk_subtrees_p = 0;
       break;
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1.C
new file mode 100644
index 0000000..52d25af
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1.C
@@ -0,0 +1,17 @@
+// PR c++/81236
+// { dg-do compile { target c++14 } }
+
+struct A { constexpr operator int() { return 24; } };
+
+struct MyType {
+  void crash() {
+    auto l = [&](auto i){
+      make_crash<i>(); // Line (1)
+    };
+
+    l(A{});
+  }
+    
+  template<int i>
+  void make_crash() {}
+};
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1a.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1a.C
new file mode 100644
index 0000000..d321a07
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-this1a.C
@@ -0,0 +1,17 @@
+// PR c++/81236
+// { dg-do compile { target c++14 } }
+
+struct A { constexpr operator int() { return 24; } };
+
+struct MyType {
+  void crash() {
+    auto l = [&](auto i){
+      MyType::make_crash<i>(); // Line (1)
+    };
+
+    l(A{});
+  }
+    
+  template<int i>
+  void make_crash() {}
+};
diff --git a/gcc/testsuite/g++.dg/template/pseudodtor3.C b/gcc/testsuite/g++.dg/template/pseudodtor3.C
index 8f1f6a7..21a68aa 100644
--- a/gcc/testsuite/g++.dg/template/pseudodtor3.C
+++ b/gcc/testsuite/g++.dg/template/pseudodtor3.C
@@ -11,7 +11,7 @@ struct A
 template <typename T> struct B
 {
   T &foo ();
-  B () { foo.~T (); }	// { dg-error "15:invalid use of member" }
+  B () { foo.~T (); }	// { dg-error "10:invalid use of member" }
 };
 
 B<int> b;
@@ -37,7 +37,7 @@ template <typename T> struct E
 {
   T &foo ();
   typedef long int U;
-  E () { foo.~U (); }	// { dg-error "10:is not of type" }
+  E () { foo.~U (); }	// { dg-error "10:invalid use of member" }
 };
 
 E<int> e;
