[cfe-dev] Error recovery when Sema finds only one (non-viable) candidate?
Nikolai Kosjar via cfe-dev
cfe-dev at lists.llvm.org
Wed Apr 24 05:38:53 PDT 2019
On 4/24/19 11:16 AM, Sam McCall via cfe-dev wrote:
> Consider the following broken code:
>
> int foo(int);
> void bar() { return foo(); }
>
> Currently it produces two diagnostics:
> - no matching call for foo
> - note: foo(int) not viable, wrong number of args
> And it produces no AST for the call (bar's CompoundStmt is empty).
>
> I'd really like it recover and produce a CallExpr to the one candidate,
> similar to what happens for typo-correction.
> 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.
Another case is when you are typing a function call and need to lookup
the function documentation - hitting F1/Help is difficult to implement
without any hint/candidate of the not-yet-completed function call.
> The new behavior might be something like:
> - only call for foo is not viable
> - note: foo(int) not viable, wrong number of args
> - bar() shouldn't return a value
> And a CallExpr emitted with no args (and maybe an 'invalid' flag).
>
> Q1: does this seem desirable in principle?
From an IDE point of view, it definitely is!
> There are some practical issues:
> - A naive implementation (https://reviews.llvm.org/D61057) 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.
> - Post recovery diagnostics can be noisy in more subtle ways. Test
> failures for naive implementation:
> https://gist.github.com/sam-mccall/bb73940e27a79ee41523e52048872f26
>
> 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.
Sounds good.
> Q2: does anyone have strong opinions about how this should work in
> practice, see hidden pitfalls, and/or want to review code?
I'm wondering whether the introduction of the invalid flag could lead to
inconsistencies somewhere (maybe analyzers/checkers?). For example, with
the new behavior a CallExpr would exist that points to a particular
candidate, having e.g. N function parameters. But the actual function
has M != N arguments (let's pretend that default arguments do not exist
for the sake of the example). It might make sense to have this new
behavior opt-in.
Besides having an (invalid) CallExpr, it would be also very useful to
have the function arguments handled. For example, if a function call is
invalid due to whatever reason, but the arguments "hello" and "there"
still could be resolved/looked-up in the current scope, the invalid
CallExpr should have appropriate DeclRefExprs children for these arguments.
This would enable go-to-definition, help/f1 and highlighting for the
arguments of not yet fully finished function calls.
I've contributed only some simple patches so far, but I could help with
testing and reviewing where I can.
> Cheers, Sam
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
More information about the cfe-dev
mailing list