I noticed a relatively simple program produced a bad error message:
template<size_t N> void foo(double (&arr)[N]) {} void bar(double (&xs)[]) { foo(xs); }
error: no matching function for call to 'foo' foo(xs); ^~~ note: candidate template ignored: could not match 'double' against 'double' void foo(double (&arr)[N]) {} ^
This seems to happen because DeduceTemplateArgumentsByTypeMatch will sometimes do this
Info.FirstArg = TemplateArgument(ParamIn); Info.SecondArg = TemplateArgument(ArgIn);
before it determines whether there's an error or not. Since the function is called recursively with the same Info, the FirstArg and SecondArg that actually cause the failure get overwritten.
My solution here is not very clean, although I tried to be minimally invasive; I'm open to suggestions for a better way to organize this. I considered llvm::SaveAndRestore but it seems to be unconditional and couldn't be "canceled" in the case of a real failure return value. I'm not familiar with any other such utilities, but maybe there is one that can make this nicer?
What if this return TDK_Success?