Previously, clang would incorrectly reject the following:
struct S {}; template<class T, int i> struct D : T {}; template<class T> void Foo(D<T, 1>); int fn() { D<D<S, 1>, 0> v; Foo(v); }
The problem is that clang initially tries to apply D<S, 1> for T in Foo, storing the result (in Deduced). Then clang tries to match 0 for 1 in Foo, would fail, and begin to consider the base classes of v (per temp.deduct.call p4.3), without resetting the original faulty assumption. This patch simply saves the deduced arguments before attempting the faulty deduction, then restores them once the faulty deduction fails.
Note: This section of code still has a somewhat related latent bug where ambiguous base class deductions are left undiagnosed, for example:
int fn2() { D<D<D<S, 1>, 1>, 0> v; Foo(v); // error, is T deduced to be S or D<S, 1>? }
Which is outlawed by temp.deduct.call p5. I have another patch that fixes this, which I'll submit once(/if) this goes through.
Can you also make this saving (and restoring) of the old deduced arguments conditional on TDF_DerivedClass and the argument type being a class type? Maybe duplicate the DeduceTemplateArguments call and put one copy inside the if (const RecordType *RecordT = ... block and the other on the else path, instead of moving the copy earlier.