diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 1ee2c57e83c..ad220980476 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7174,6 +7174,7 @@ extern tree get_innermost_template_args		(tree, int);
 extern void maybe_begin_member_template_processing (tree);
 extern void maybe_end_member_template_processing (void);
 extern tree finish_member_template_decl		(tree);
+extern void add_dummy_template_parameter_level	();
 extern void begin_template_parm_list		(void);
 extern bool begin_specialization		(void);
 extern void reset_specialization		(void);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f4b9d9673fb..f1ef1dbde0f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -689,6 +689,16 @@ strip_innermost_template_args (tree args, int extra_levels)
   return new_args;
 }
 
+/* Add a dummy template parameter level to current_template_parms.  */
+
+void
+add_dummy_template_parameter_level ()
+{
+  current_template_parms = tree_cons (size_int (processing_template_decl),
+				      make_tree_vec (0),
+				      current_template_parms);
+}
+
 /* We've got a template header coming up; push to a new level for storing
    the parms.  */
 
@@ -715,10 +725,7 @@ begin_template_parm_list (void)
   note_template_header (0);
 
   /* Add a dummy parameter level while we process the parameter list.  */
-  current_template_parms
-    = tree_cons (size_int (processing_template_decl),
-		 make_tree_vec (0),
-		 current_template_parms);
+  add_dummy_template_parameter_level ();
 }
 
 /* This routine is called when a specialization is declared.  If it is
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index cd1956497f8..7e2179412b2 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3143,6 +3143,9 @@ finish_compound_literal (tree type, tree compound_literal,
 	pedwarn (input_location, OPT_Wc__23_extensions,
 		 "%<auto{x}%> only available with "
 		 "%<-std=c++2b%> or %<-std=gnu++2b%>");
+      auto ctp = make_temp_override (current_template_parms);
+      if (processing_template_decl && !current_template_parms)
+	add_dummy_template_parameter_level ();
       type = do_auto_deduction (type, compound_literal, type, complain,
 				adc_variable_type);
       if (type == error_mark_node)
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 3fb651a02ba..af20315c9e4 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -2202,6 +2202,7 @@ build_functional_cast_1 (location_t loc, tree exp, tree parms,
   if (tree anode = type_uses_auto (type))
     {
       tree init;
+      auto ctp = make_temp_override (current_template_parms);
       if (CLASS_PLACEHOLDER_TEMPLATE (anode))
 	init = parms;
       /* C++23 auto(x).  */
@@ -2213,6 +2214,8 @@ build_functional_cast_1 (location_t loc, tree exp, tree parms,
 	    pedwarn (loc, OPT_Wc__23_extensions,
 		     "%<auto(x)%> only available with "
 		     "%<-std=c++2b%> or %<-std=gnu++2b%>");
+	  if (processing_template_decl && !current_template_parms)
+	    add_dummy_template_parameter_level ();
 	}
       else
 	{
diff --git a/gcc/testsuite/g++.dg/cpp23/auto-fncast9.C b/gcc/testsuite/g++.dg/cpp23/auto-fncast9.C
new file mode 100644
index 00000000000..b92a5f7b320
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp23/auto-fncast9.C
@@ -0,0 +1,35 @@
+// PR c++/103408
+// { dg-do compile { target c++23 } }
+
+int bad1() requires (auto(true)); // { dg-error "constraints on a non-templated function" }
+
+template<bool B>
+int f1() requires (auto(B));
+
+template<typename T>
+struct S { T t; constexpr operator bool() { return true; } };
+
+int bad2() requires (bool(S{1})); // { dg-error "constraints on a non-templated function" }
+int bad3() requires (bool(S(1))); // { dg-error "constraints on a non-templated function" }
+
+template<int N>
+int f2() requires (bool(S{N}));
+
+template<int N>
+int f3() requires (bool(S(N)));
+
+void
+g ()
+{
+  f1<true>();
+  f2<42>();
+  f3<42>();
+}
+
+static_assert(requires { auto(0); });
+static_assert(requires { auto(auto(0)); });
+static_assert(requires { auto(auto(auto(0))); });
+
+static_assert(requires { auto{0}; });
+static_assert(requires { auto{auto{0}}; });
+static_assert(requires { auto{auto{auto{0}}}; });
