sammccall added a comment.

driveby thoughts, but please don't block on them.

(if this fix is a heuristic that fixes a common crash but isn't completely 
correct, that may still be worth landing but warrants a fixme)



================
Comment at: clang-tools-extra/clangd/AST.cpp:832
           continue;
+        // Check that this expands all the way until the last parameter.
+        auto ParamEnd = It + Parameters.size() - 1;
----------------
The essence of this test seems to be "if we can't rule it out by counting 
parameters, it must be right" which... doesn't seem very robust? Am I missing 
something?

AIUI the idea here is that
A) `foo(pack...)` is "expanded all the way" into consecutive arguments
B) `foo(pack)...` is not considered forwarding for our purposes
C) we want to treat `foo(bar(pack)...)` specially if `bar` is "just a cast" 
like move or forward

The difference between cases A and B aren't about counting arguments though, 
they're about what operations occur intercede between `pack` and the `...` 
operator. (i.e. `foo((&pack)...)` is fine for the same reason `forward` is.

This seems like something best handled by:
 - finding the `PackExpansionExpr` controlling `pack` in the non-instantiated 
template AST
 - walking down to try to find `pack`
 - continue as we walk through e.g. parens or std::forward
 - bail out if we walk through something unknown (e.g. another function call)

Does this seem sensible/feasible?
(Walking up from `pack` is nicer but the AST doesn't support walking up well...)


================
Comment at: clang-tools-extra/clangd/AST.cpp:833-837
+        auto ParamEnd = It + Parameters.size() - 1;
+        assert(std::distance(Args.begin(), ParamEnd) <
+                   std::distance(Args.begin(), Args.end()) &&
+               "Only functions with greater than or equal number of parameters 
"
+               "should be checked.");
----------------
upsj wrote:
> I think it would be safer to check this explicitly, since advancing the 
> iterator past its end might be UB (depending on the implementation).
Right, this is definitely UB as written.

FWIW I find this easier to understand in classic bounds-check form:

if ((It - Args.begin()) + Parameters.size() >= Args.size())


================
Comment at: clang-tools-extra/clangd/unittests/InlayHintTests.cpp:1468
+    void bar(Args... args) {
+      foo(id($param1[[args]], $param2[[1]])...);
+    }
----------------
(Just so I understand: these are getting hinted due to the "only instantiation" 
logic, right?)


================
Comment at: clang-tools-extra/clangd/unittests/InlayHintTests.cpp:1471
+    void foo() {
+      bar(1, 2);
+    }
----------------
could reasonably expect this to be `bar(a:1, 2)` or `bar(a:1, a:2)` - leave a 
comment explaining why?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130260/new/

https://reviews.llvm.org/D130260

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to