jcsxky wrote: details: ```cpp template<typename FunctionTemplateParam> constexpr int FuncAlign(int param = alignof(FunctionTemplateParam));
template <> template<typename FunctionTemplateParam> constexpr int Problem<int>::FuncAlign(int param) { // depth of FunctionTemplateParam in default // initialization of alignof(FunctionTemplateParam) is still 1 return param; } ``` Add template instantiation args of context(`TemplateClassSpecialize`) to `MultiLevelTemplateArgumentList` and level of `MultiLevelTemplateArgumentList` is 2, and make `alignof(FunctionTemplateParam)` instantiated successfully. ```cpp void run( std::function<void(T&)> f1 = [](auto&&) {}, std::function<void(T&)> f2 = [](auto&&) {}); template <typename T> void A<T>::run(std::function<void(T&)> f1, std::function<void(T&)> f2) { Helper h(f2); } ``` Here we can't add template instantiation args of context because level of `MultiLevelTemplateArgumentList` in this case is 2 and it's the same with depth of `auto&&` . This remind us make the condition ```cpp const FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate(); if (PrimaryTemplate && PrimaryTemplate->isOutOfLine()) ``` I think this should distinguish the first case from others. https://github.com/llvm/llvm-project/pull/80288 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits