Skip to content

Commit 99df95f

Browse files
committed
[clang][CodeComplete] Fix crash on ParenListExprs
Fixes clangd/clangd#676. Differential Revision: https://reviews.llvm.org/D95935
1 parent a92ceea commit 99df95f

File tree

4 files changed

+30
-2
lines changed

4 files changed

+30
-2
lines changed

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5168,6 +5168,15 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
51685168
if (!Base || !CodeCompleter)
51695169
return;
51705170

5171+
// Peel off the ParenListExpr by chosing the last one, as they don't have a
5172+
// predefined type.
5173+
if (auto *PLE = llvm::dyn_cast<ParenListExpr>(Base))
5174+
Base = PLE->getExpr(PLE->getNumExprs() - 1);
5175+
if (OtherOpBase) {
5176+
if (auto *PLE = llvm::dyn_cast<ParenListExpr>(OtherOpBase))
5177+
OtherOpBase = PLE->getExpr(PLE->getNumExprs() - 1);
5178+
}
5179+
51715180
ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow);
51725181
if (ConvertedBase.isInvalid())
51735182
return;
@@ -5597,12 +5606,17 @@ ProduceSignatureHelp(Sema &SemaRef, Scope *S,
55975606
QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn,
55985607
ArrayRef<Expr *> Args,
55995608
SourceLocation OpenParLoc) {
5600-
if (!CodeCompleter)
5609+
if (!CodeCompleter || !Fn)
56015610
return QualType();
56025611

5612+
// If we have a ParenListExpr for LHS, peel it off by chosing the last expr.
5613+
// As ParenListExprs don't have a predefined type.
5614+
if (auto *PLE = llvm::dyn_cast<ParenListExpr>(Fn))
5615+
Fn = PLE->getExpr(PLE->getNumExprs() - 1);
5616+
56035617
// FIXME: Provide support for variadic template functions.
56045618
// Ignore type-dependent call expressions entirely.
5605-
if (!Fn || Fn->isTypeDependent() || anyNullArguments(Args))
5619+
if (Fn->isTypeDependent() || anyNullArguments(Args))
56065620
return QualType();
56075621
// In presence of dependent args we surface all possible signatures using the
56085622
// non-dependent args in the prefix. Afterwards we do a post filtering to make

clang/test/CodeCompletion/function-overloads.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ namespace NS {
2121
void test_adl() {
2222
NS::X x;
2323
g(x, x);
24+
(void)(f)(1, 2, 3);
25+
(void)(test, test, test, f)(1, 2, 3);
2426
}
2527

2628
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
@@ -31,6 +33,10 @@ void test_adl() {
3133
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:21 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
3234
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:7 %s -o - | \
3335
// RUN: FileCheck -check-prefix=CHECK-CC5 %s
36+
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:24:13 %s -o - | \
37+
// RUN: FileCheck -check-prefix=CHECK-CC1 %s
38+
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:25:31 %s -o - | \
39+
// RUN: FileCheck -check-prefix=CHECK-CC1 %s
3440
// CHECK-CC1: OVERLOAD: [#int#]f(<#float x#>, float y)
3541
// CHECK-CC1: OVERLOAD: [#int#]f(<#int i#>)
3642
// CHECK-CC1-NOT, CHECK-CC2-NOT: OVERLOAD: A(

clang/test/CodeCompletion/member-access.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,10 @@ void test3(struct Point2 *p) {
2929

3030
// RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:24:5 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
3131
// CHECK-CC3: x (requires fix-it: {24:4-24:5} to "->")
32+
33+
void test4(struct Point *p) {
34+
(int)(p)->x;
35+
(int)(0,1,2,3,4,p)->x;
36+
}
37+
// RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:34:13 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
38+
// RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:35:23 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s

clang/unittests/Sema/CodeCompleteTest.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ TEST(PreferredTypeTest, NoCrashOnInvalidTypes) {
488488
auto y = new decltype(&1)(^);
489489
// GNU decimal type extension is not supported in clang.
490490
auto z = new _Decimal128(^);
491+
void foo() { (void)(foo)(^); }
491492
)cpp";
492493
EXPECT_THAT(collectPreferredTypes(Code), Each("NULL TYPE"));
493494
}

0 commit comments

Comments
 (0)