[PATCH] D95935: [clang][CodeComplete] Fix crash on ParenListExprs

Kadir Cetinkaya via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 3 04:28:58 PST 2021


kadircet updated this revision to Diff 321054.
kadircet added a comment.

- Also handle memberrefexpr case.

Fixes https://github.com/clangd/clangd/issues/676.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D95935

Files:
  clang/lib/Sema/SemaCodeComplete.cpp
  clang/test/CodeCompletion/function-overloads.cpp
  clang/test/CodeCompletion/member-access.c
  clang/unittests/Sema/CodeCompleteTest.cpp


Index: clang/unittests/Sema/CodeCompleteTest.cpp
===================================================================
--- clang/unittests/Sema/CodeCompleteTest.cpp
+++ clang/unittests/Sema/CodeCompleteTest.cpp
@@ -488,6 +488,7 @@
     auto y = new decltype(&1)(^);
     // GNU decimal type extension is not supported in clang.
     auto z = new _Decimal128(^);
+    void foo() { (void)(foo)(^); }
   )cpp";
   EXPECT_THAT(collectPreferredTypes(Code), Each("NULL TYPE"));
 }
Index: clang/test/CodeCompletion/member-access.c
===================================================================
--- clang/test/CodeCompletion/member-access.c
+++ clang/test/CodeCompletion/member-access.c
@@ -29,3 +29,10 @@
 
 // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:24:5 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
 // CHECK-CC3: x (requires fix-it: {24:4-24:5} to "->")
+
+void test4(struct Point *p) {
+  (int)(p)->x;
+  (int)(0,1,2,3,4,p)->x;
+}
+// RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:34:13 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:35:23 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
Index: clang/test/CodeCompletion/function-overloads.cpp
===================================================================
--- clang/test/CodeCompletion/function-overloads.cpp
+++ clang/test/CodeCompletion/function-overloads.cpp
@@ -21,6 +21,8 @@
 void test_adl() {
   NS::X x;
   g(x, x);
+  (void)(f)(1, 2, 3);
+  (void)(test, test, test, f)(1, 2, 3);
 }
 
 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
@@ -31,6 +33,10 @@
 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:21 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:7 %s -o - | \
 // RUN:    FileCheck -check-prefix=CHECK-CC5 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:24:13 %s -o - | \
+// RUN:    FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:25:31 %s -o - | \
+// RUN:    FileCheck -check-prefix=CHECK-CC1 %s
 // CHECK-CC1: OVERLOAD: [#int#]f(<#float x#>, float y)
 // CHECK-CC1: OVERLOAD: [#int#]f(<#int i#>)
 // CHECK-CC1-NOT, CHECK-CC2-NOT: OVERLOAD: A(
Index: clang/lib/Sema/SemaCodeComplete.cpp
===================================================================
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ clang/lib/Sema/SemaCodeComplete.cpp
@@ -5168,6 +5168,14 @@
   if (!Base || !CodeCompleter)
     return;
 
+  // Peel off the ParenListExpr by chosing the last one.
+  if (auto *PLE = llvm::dyn_cast<ParenListExpr>(Base))
+    Base = PLE->getExpr(PLE->getNumExprs() - 1);
+  if (OtherOpBase) {
+    if (auto *PLE = llvm::dyn_cast<ParenListExpr>(OtherOpBase))
+      OtherOpBase = PLE->getExpr(PLE->getNumExprs() - 1);
+  }
+
   ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow);
   if (ConvertedBase.isInvalid())
     return;
@@ -5597,12 +5605,16 @@
 QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn,
                                         ArrayRef<Expr *> Args,
                                         SourceLocation OpenParLoc) {
-  if (!CodeCompleter)
+  if (!CodeCompleter || !Fn)
     return QualType();
 
+  // If we have a ParenListExpr for LHS, peel it off by chosing the last expr.
+  if (auto *PLE = llvm::dyn_cast<ParenListExpr>(Fn))
+    Fn = PLE->getExpr(PLE->getNumExprs() - 1);
+
   // FIXME: Provide support for variadic template functions.
   // Ignore type-dependent call expressions entirely.
-  if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args))
+  if (Fn->isTypeDependent() || anyNullArguments(Args))
     return QualType();
   // In presence of dependent args we surface all possible signatures using the
   // non-dependent args in the prefix. Afterwards we do a post filtering to make


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95935.321054.patch
Type: text/x-patch
Size: 3978 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210203/632fe440/attachment.bin>


More information about the cfe-commits mailing list