Skip to content

[clangd] Avoid crash when summarizing pointer-to-member expr for block-end hint #76492

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

Merged
merged 1 commit into from
Dec 29, 2023

Conversation

HighCommander4
Copy link
Collaborator

@llvmbot
Copy link
Member

llvmbot commented Dec 28, 2023

@llvm/pr-subscribers-clangd

Author: Nathan Ridge (HighCommander4)

Changes

Fixes clangd/clangd#1873


Full diff: https://github.com/llvm/llvm-project/pull/76492.diff

2 Files Affected:

  • (modified) clang-tools-extra/clangd/InlayHints.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/unittests/InlayHintTests.cpp (+13)
diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp
index 3da047f9542138..fd28b48b5a0b02 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -286,7 +286,7 @@ std::string summarizeExpr(const Expr *E) {
     // Step through implicit nodes that clang doesn't classify as such.
     std::string VisitCXXMemberCallExpr(const CXXMemberCallExpr *E) {
       // Call to operator bool() inside if (X): dispatch to X.
-      if (E->getNumArgs() == 0 &&
+      if (E->getNumArgs() == 0 && E->getMethodDecl() &&
           E->getMethodDecl()->getDeclName().getNameKind() ==
               DeclarationName::CXXConversionFunctionName &&
           E->getSourceRange() ==
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index 20c1cdd985dbc0..ea5ee18f1da65c 100644
--- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -2172,6 +2172,19 @@ TEST(BlockEndHints, Macro) {
                       ExpectedHint{" // struct S1", "S1"});
 }
 
+TEST(BlockEndHints, PointerToMemberFunction) {
+  // Do not crash trying to summarize `a->*p`.
+  assertBlockEndHints(R"cpp(
+    class A {};
+    using Predicate = bool(A::*)();
+    void foo(A* a, Predicate p) {
+      if ((a->*p)()) {
+      $ptrmem[[}]]
+    } // suppress
+  )cpp",
+                      ExpectedHint{" // if", "ptrmem"});
+}
+
 // FIXME: Low-hanging fruit where we could omit a type hint:
 //  - auto x = TypeName(...);
 //  - auto x = (TypeName) (...);

Copy link
Collaborator

@hokein hokein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Can you add your analysis (clangd/clangd#1873 (comment)) to the commit description, I think it is useful to have it in the commit log.

btw, it looks like there is a FIXME (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ExprCXX.cpp#L677) for supporting this particular case.

…k-end hint

For calls through a pointer to member, CXXMemberCallExpr::getCallee() is
a BinaryOperator with operator ->* (after unwrapping parens).

getMethodDecl() only returns non-null if the callee is a MemberExpr.

Fixes clangd/clangd#1873
@HighCommander4
Copy link
Collaborator Author

btw, it looks like there is a FIXME (https://github.com/llvm/llvm-project/blob/main/clang/lib/AST/ExprCXX.cpp#L677) for supporting this particular case.

I saw it, but I'm not clear on what that would look like.

Which member function a member function pointer resolves to is a runtime property of the pointer variable. I don't think we can produce a CXXMethodDecl there unless perhaps the pointer is a constant expression, which seems like an edge case.

@HighCommander4 HighCommander4 merged commit dbd1fb8 into llvm:main Dec 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clangd crash in Namer::VisitCXXMemberCallExpr() in InlayHints.cpp
3 participants