<div dir="ltr"><div dir="ltr">Consider the following broken code:<div><br></div><div>  int foo(int);</div><div>  void bar() { return foo(); }</div><div><br></div><div>Currently it produces two diagnostics:</div><div>  - no matching call for foo</div><div>  - note: foo(int) not viable, wrong number of args</div><div>And it produces no AST for the call (bar's CompoundStmt is empty).</div><div><br></div><div>I'd really like it recover and produce a CallExpr to the one candidate, similar to what happens for typo-correction.</div><div>My own motivation is to get go-to-definition in libclang/clangd to work better with broken code, though I think there are other benefits.<br></div><div><br></div><div>The new behavior might be something like:</div><div> - only call for foo is not viable</div><div> - note: foo(int) not viable, wrong number of args</div><div> - bar() shouldn't return a value</div><div>And a CallExpr emitted with no args (and maybe an 'invalid' flag).</div><div><br></div><div>Q1: does this seem desirable in principle?</div><div><br></div><div>---</div><div><br></div><div>There are some practical issues:</div><div> - A naive implementation (<a href="https://reviews.llvm.org/D61057">https://reviews.llvm.org/D61057</a>) sometimes emits pre-recovery "not viable: X" diagnostics and post-recovery "error: X" for the same reason X. e.g. for cuda device->host calls.</div><div> - Post recovery diagnostics can be noisy in more subtle ways. Test failures for naive implementation: <a href="https://gist.github.com/sam-mccall/bb73940e27a79ee41523e52048872f26">https://gist.github.com/sam-mccall/bb73940e27a79ee41523e52048872f26</a></div><div><br></div><div>Maybe it's best to start with only simple cases, e.g. recovering only from too many/too few arguments doesn't break any tests, and covers a lot of broken-code cases.</div><div><br></div><div>Q2: does anyone have strong opinions about how this should work in practice, see hidden pitfalls, and/or want to review code?</div><div><br></div><div>Cheers, Sam</div></div></div>