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

getRawCommentForAnyRedecl can fail to return definition comment #108145

Closed
HighCommander4 opened this issue Sep 11, 2024 · 3 comments · Fixed by #108475
Closed

getRawCommentForAnyRedecl can fail to return definition comment #108145

HighCommander4 opened this issue Sep 11, 2024 · 3 comments · Fixed by #108475
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" regression

Comments

@HighCommander4
Copy link
Collaborator

While working on a clangd enhancement (#67802), @ckandeler and I have run into what I believe is a bug in ASTContext::getRawCommentForAnyRedecl(): when called on the definition of a function or class, it can fail to return the comment above the definition (i.e. incorrectly return null instead), if it was previously called on a (non-defining) declaration at a time when the definition wasn't yet added to the redecl chain.

I wrote a (failing) unit test demonstrating the issue at HighCommander4@9933075.

The bug is a regression from f31d8df, which introduced the cache CommentlessRedeclChains and related data structures. (I verified this with a local backout of the patch, which makes my unit test pass.)

@jkorous-apple and @gribozavr, as author and reviewer of the regressing patch, could you advise what an appropriate fix would be?


Here are some more details regarding the bug:

The failing unit test processes the following code:

void f();

// f is the best
void f() {}

with an ASTConsumer that calls ASTContext::getRawCommentForAnyRedecl() as soon as a declaration is parsed and given to the consumer.

(I assume this is a valid use of getRawCommentForAnyRedecl(), i.e. it's not the intention to require that the function only be called once the whole AST is built, otherwise I don't see what would be the purpose of having caches like CommentlessRedeclChains at all. Please let me know if I misunderstood.)

When getRawCommentForAnyRedecl() is first called, for the non-defining declaration of f(), the definition has not been parsed and added to the redecl chain yet. This results in CommentslessRedeclChains containing an entry mapping this declaration to itself here.

When the function is called a second time for the definition of f(), the redecl chain of that contains itself (the definition) as the first element, and the non-defining declaration as the second. The previously stored mapping is looked up here, and results in the loop skipping the definition here, and therefore never checking the definition for a comment.

Based on the above debugging, I don't quite understand how this caching mechanism is supposed to work.

@HighCommander4 HighCommander4 added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Sep 11, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Sep 11, 2024

@llvm/issue-subscribers-clang-frontend

Author: Nathan Ridge (HighCommander4)

While working on a clangd enhancement (https://github.com//pull/67802), @ckandeler and I have run into what I believe is a bug in `ASTContext::getRawCommentForAnyRedecl()`: when called on the **definition** of a function or class, it can fail to return the comment above the definition (i.e. incorrectly return null instead), if it was previously called on a (non-defining) declaration at a time when the definition wasn't yet added to the redecl chain.

I wrote a (failing) unit test demonstrating the issue at HighCommander4@9933075.

The bug is a regression from f31d8df, which introduced the cache CommentlessRedeclChains and related data structures. (I verified this with a local backout of the patch, which makes my unit test pass.)

@jkorous-apple and @gribozavr, as author and reviewer of the regressing patch, could you advise what an appropriate fix would be?


Here are some more details regarding the bug:

The failing unit test processes the following code:

void f();

// f is the best
void f() {}

with an ASTConsumer that calls ASTContext::getRawCommentForAnyRedecl() as soon as a declaration is parsed and given to the consumer.

(I assume this is a valid use of getRawCommentForAnyRedecl(), i.e. it's not the intention to require that the function only be called once the whole AST is built, otherwise I don't see what would be the purpose of having caches like CommentlessRedeclChains at all. Please let me know if I misunderstood.)

When getRawCommentForAnyRedecl() is first called, for the non-defining declaration of f(), the definition has not been parsed and added to the redecl chain yet. This results in CommentslessRedeclChains containing an entry mapping this declaration to itself [here](https://searchfox.org/llvm/rev/b0ffaa79050460d724eec1b12363c439b43d5ae5/clang/lib/AST/ASTContext.cpp#464).

When the function is called a second time for the definition of f(), the redecl chain of that contains itself (the definition) as the first element, and the non-defining declaration as the second. The previously stored mapping is looked up [here](https://searchfox.org/llvm/rev/b0ffaa79050460d724eec1b12363c439b43d5ae5/clang/lib/AST/ASTContext.cpp#445), and results in the loop skipping the definition [here](https://searchfox.org/llvm/rev/b0ffaa79050460d724eec1b12363c439b43d5ae5/clang/lib/AST/ASTContext.cpp#455), and therefore never checking the definition for a comment.

Based on the above debugging, I don't quite understand how this caching mechanism is supposed to work.

@shafik
Copy link
Collaborator

shafik commented Sep 11, 2024

CC @Bigcheese

@HighCommander4
Copy link
Collaborator Author

@jkorous-apple and @gribozavr, as author and reviewer of the regressing patch, could you advise what an appropriate fix would be?

I thought of a fix and submitted it with my unit test at #108475.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" regression
Projects
None yet
3 participants