Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clangd] Incorrect navigation caused by deducing this #116335

Open
ymyh opened this issue Nov 15, 2024 · 5 comments · May be fixed by #117841
Open

[clangd] Incorrect navigation caused by deducing this #116335

ymyh opened this issue Nov 15, 2024 · 5 comments · May be fixed by #117841
Labels

Comments

@ymyh
Copy link

ymyh commented Nov 15, 2024

struct B
{
    template<typename Self>
    auto bar(this Self &&) 
    {
        return 0;
    }

    auto bar2(this B &&)
    {
        return 0;
    }
};

struct A
{
    auto foo()
    {
        return B{};
    }
};

auto baz(int n)
{
    return n;
}

int main()
{
    A a{};
    baz(a.foo().bar());

    A a2{};
    int n  = a2.foo().bar2();
}

incorrect navigation of a.foo and a to baz, a2.foo and a2 to n

@llvmbot
Copy link
Member

llvmbot commented Nov 15, 2024

@llvm/issue-subscribers-clangd

Author: dayDreamingSaltyFish (ymyh)

```c++ struct B { template<typename Self> auto bar(this Self &&) { return 0; }
auto bar2(this B &amp;&amp;)
{
    return 0;
}

};

struct A
{
auto foo()
{
return B{};
}
};

auto baz(int n)
{
return n;
}

int main()
{
A a{};
baz(a.foo().bar());

A a2{};
int n  = a2.foo().bar2();

}

incorrect navigation of a.foo and a to baz, a2.foo and a2 to n

</details>

@HighCommander4
Copy link
Collaborator

Slightly reduced:

struct S
{
    int bar(this S&);
};

int main()
{
    S waldo;
    int x = waldo.bar();
}

Go-to-def on waldo in waldo.bar() incorrectly goes to x.

@HighCommander4
Copy link
Collaborator

SelectionTree is incorrectly selecting the x.

Here is a SelectionTree trace:

Computing selection for </clangd-test/TestTU.cpp:7:19, col:24>
 skip: CXXRecordDecl </clangd-test/TestTU.cpp:2:9, line:4:9>
 push: FunctionDecl </clangd-test/TestTU.cpp:5:9, line:8:9>
  push: NestedNameSpecifierLoc <<invalid sloc>>
  pop: NestedNameSpecifierLoc
  skip: FunctionProtoTypeLoc </clangd-test/TestTU.cpp:5:9, col:18>
  push: CompoundStmt </clangd-test/TestTU.cpp:5:20, line:8:9>
   skip: DeclStmt </clangd-test/TestTU.cpp:6:11, col:18>
   push: DeclStmt </clangd-test/TestTU.cpp:7:11, col:30>
    push: VarDecl </clangd-test/TestTU.cpp:7:11, col:29>
     push: NestedNameSpecifierLoc <<invalid sloc>>
     pop: NestedNameSpecifierLoc
     skip: BuiltinTypeLoc </clangd-test/TestTU.cpp:7:11>
     skip: CallExpr </clangd-test/TestTU.cpp:7:25, col:29>
    pop: VarDecl
     hit selection: </clangd-test/TestTU.cpp:7:11, col:29>
   pop: DeclStmt
  pop: CompoundStmt
 pop: FunctionDecl
Built selection tree
 TranslationUnitDecl 
   FunctionDecl void foo()
     CompoundStmt { …
       DeclStmt int x = bar(waldo);
        .VarDecl int x = bar(waldo)

@HighCommander4
Copy link
Collaborator

Basically, the hit-testing algorithm skips the CallExpr node for waldo.bar() altogether, because CallExpr::getBeginLoc() returns the callee's begin loc, which is the bar token, so we think the waldo token falls outside of the CallExpr.

@HighCommander4
Copy link
Collaborator

HighCommander4 commented Nov 20, 2024

CallExpr::getBeginLoc() returns the callee's begin loc, which is the bar token

Let's start by seeing if we can get this fixed upstream in the AST: #116928

HighCommander4 added a commit to HighCommander4/llvm-project that referenced this issue Nov 27, 2024
…ject parameter

The explicit object parameter is written before the callee expression,
so the begin location should come from the explicit object parameter.

Fixes llvm#116335
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
4 participants