diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 91b45a1a69511600ac4da7e1705af5e167cb190b..a85f4d507501bec257e1f4ea1dd2526e2922491d 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -586,17 +586,21 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
 
 	  bool pushed = false;
 	  tree ctx = DECL_CONTEXT (member);
-	  if (!currently_open_class (ctx)
-	      && !LOCAL_CLASS_P (ctx))
+
+	  processing_template_decl_sentinel ptds (/*reset*/false);
+	  if (!currently_open_class (ctx))
 	    {
-	      push_to_top_level ();
+	      if (!LOCAL_CLASS_P (ctx))
+		push_to_top_level ();
+	      else
+		/* push_to_top_level would lose the necessary function context,
+		   just reset processing_template_decl.  */
+		processing_template_decl = 0;
 	      push_nested_class (ctx);
 	      push_deferring_access_checks (dk_no_deferred);
 	      pushed = true;
 	    }
 
-	  gcc_checking_assert (!processing_template_decl);
-
 	  inject_this_parameter (ctx, TYPE_UNQUALIFIED);
 
 	  start_lambda_scope (member);
@@ -619,7 +623,8 @@ get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
 	    {
 	      pop_deferring_access_checks ();
 	      pop_nested_class ();
-	      pop_from_top_level ();
+	      if (!LOCAL_CLASS_P (ctx))
+		pop_from_top_level ();
 	    }
 
 	  input_location = sloc;
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-local-class1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-local-class1.C
new file mode 100644
index 0000000000000000000000000000000000000000..7498327981b6eab2a961dc5759cbe56bf0d72cdd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-local-class1.C
@@ -0,0 +1,10 @@
+// PR c++/100054
+// { dg-do compile { target c++14 } }
+
+template <class T>
+void f() {
+  struct A { T m{}; };
+  [](auto){ return A{}; };
+}
+
+template void f<int>();