https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110323
--- Comment #8 from Marek Polacek <mpolacek at gcc dot gnu.org> --- (In reply to Patrick Palka from comment #7) > I noticed we emit the function if we turn it into a non-member: > > #include <type_traits> > > constexpr int VAL = 1; > > template <int B> > void bar(typename std::conditional<B==VAL, int, float>::type arg) { > } > > template void bar<1>(int arg); > > I wonder why this bug seems specific to member functions? Good question. It's because in this case bar is marked as force_output here: /* When not optimizing, also output the static functions. (see PR24561), but don't do so for always_inline functions, functions declared inline and nested functions. These were optimized out in the original implementation and it is unclear whether we want to change the behavior here. */ if (((!opt_for_fn (decl, optimize) || flag_keep_static_functions || node->no_reorder) && !node->cpp_implicit_alias && !DECL_DISREGARD_INLINE_LIMITS (decl) && !DECL_DECLARED_INLINE_P (decl) && !(DECL_CONTEXT (decl) && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL)) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)) node->force_output = 1; and when deciding if we ought to emit the fn in symtab_node::needed_p we do: /* If the user told us it is used, then it must be so. */ if (force_output) return true; With -O the fn isn't emitted.