Skip to content

Commit 7fc6c60

Browse files
committed
[clang][CodeComplete] Ensure there are no crashes when completing with ParenListExprs as LHS
Differential Revision: https://reviews.llvm.org/D96950
1 parent 99df95f commit 7fc6c60

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5158,25 +5158,32 @@ class ConceptInfo {
51585158

51595159
llvm::DenseMap<const IdentifierInfo *, Member> Results;
51605160
};
5161+
5162+
// If \p Base is ParenListExpr, assume a chain of comma operators and pick the
5163+
// last expr. We expect other ParenListExprs to be resolved to e.g. constructor
5164+
// calls before here. (So the ParenListExpr should be nonempty, but check just
5165+
// in case)
5166+
Expr *unwrapParenList(Expr *Base) {
5167+
if (auto *PLE = llvm::dyn_cast_or_null<ParenListExpr>(Base)) {
5168+
if (PLE->getNumExprs() == 0)
5169+
return nullptr;
5170+
Base = PLE->getExpr(PLE->getNumExprs() - 1);
5171+
}
5172+
return Base;
5173+
}
5174+
51615175
} // namespace
51625176

51635177
void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
51645178
Expr *OtherOpBase,
51655179
SourceLocation OpLoc, bool IsArrow,
51665180
bool IsBaseExprStatement,
51675181
QualType PreferredType) {
5182+
Base = unwrapParenList(Base);
5183+
OtherOpBase = unwrapParenList(OtherOpBase);
51685184
if (!Base || !CodeCompleter)
51695185
return;
51705186

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-
51805187
ExprResult ConvertedBase = PerformMemberExprBaseConversion(Base, IsArrow);
51815188
if (ConvertedBase.isInvalid())
51825189
return;
@@ -5606,14 +5613,10 @@ ProduceSignatureHelp(Sema &SemaRef, Scope *S,
56065613
QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn,
56075614
ArrayRef<Expr *> Args,
56085615
SourceLocation OpenParLoc) {
5616+
Fn = unwrapParenList(Fn);
56095617
if (!CodeCompleter || !Fn)
56105618
return QualType();
56115619

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-
56175620
// FIXME: Provide support for variadic template functions.
56185621
// Ignore type-dependent call expressions entirely.
56195622
if (Fn->isTypeDependent() || anyNullArguments(Args))

0 commit comments

Comments
 (0)