================
@@ -3949,28 +3949,15 @@ TemplateDeductionResult 
Sema::FinishTemplateArgumentDeduction(
       TemplateArgumentList::CreateCopy(Context, CanonicalBuilder);
   Info.reset(SugaredDeducedArgumentList, CanonicalDeducedArgumentList);
 
+  FunctionTemplate = FunctionTemplate->getMostRecentDecl();
+
----------------
zyn0217 wrote:

So this is where the magic happens:

To help us get a bigger picture of the patch, let's take an example from your 
test case,

```cpp
namespace t1 {
  template<int N> struct A {
    template<class C> friend auto cica(const A<N-1>&, C) {
      return N;
    }
  };

  template<> struct A<0> {
    template<class C> friend auto cica(const A<0>&, C);
  };

  void test() {

    (void)A<1>{};
    cica(A<0>{}, 0);
  }
} // namespace t1
```

Previously, we would crash in `BuildExpressionFromIntegralTemplateArgument()` 
because we're trying to substitute the NTTP `N` in the return expression with a 
template argument `<int>`. That is due to an incorrect MLTAL provided by 
`getTemplateInstantiationArgs()`, when instantiating the function definition of 
`cica` for the purpose of return type deduction.

The MLTAL is missing the outer `N` because the collected template arguments are 
from a friend function whose parent is an explicit template specialization, 
`template <> struct A<0>`. And we don't do anything else for an explicit 
specialization, so we're left with only one level of template arguments, which 
is just `<int>`.

The approach here did the trick that, instead of instantiating the function 
from the explicit specialization, it finds the declaration that is created by 
the last implicit instantiation of the corresponding explicit specialization, 
namely the specialization for `A<N>`.

I presume changes elsewhere are tweaking to adapt the new behavior here, right?

https://github.com/llvm/llvm-project/pull/110387
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to