Author: Kadir Cetinkaya Date: 2021-02-23T11:13:07+01:00 New Revision: 7fc6c60608e416e7f8f5c194768c6dd511449c1b
URL: https://github.com/llvm/llvm-project/commit/7fc6c60608e416e7f8f5c194768c6dd511449c1b DIFF: https://github.com/llvm/llvm-project/commit/7fc6c60608e416e7f8f5c194768c6dd511449c1b.diff LOG: [clang][CodeComplete] Ensure there are no crashes when completing with ParenListExprs as LHS Differential Revision: https://reviews.llvm.org/D96950 Added: Modified: clang/lib/Sema/SemaCodeComplete.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp index 40ea0f5d24b3..be04970979b3 100644 --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -5158,6 +5158,20 @@ class ConceptInfo { llvm::DenseMap<const IdentifierInfo *, Member> Results; }; + +// If \p Base is ParenListExpr, assume a chain of comma operators and pick the +// last expr. We expect other ParenListExprs to be resolved to e.g. constructor +// calls before here. (So the ParenListExpr should be nonempty, but check just +// in case) +Expr *unwrapParenList(Expr *Base) { + if (auto *PLE = llvm::dyn_cast_or_null<ParenListExpr>(Base)) { + if (PLE->getNumExprs() == 0) + return nullptr; + Base = PLE->getExpr(PLE->getNumExprs() - 1); + } + return Base; +} + } // namespace void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, @@ -5165,18 +5179,11 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base, SourceLocation OpLoc, bool IsArrow, bool IsBaseExprStatement, QualType PreferredType) { + Base = unwrapParenList(Base); + OtherOpBase = unwrapParenList(OtherOpBase); if (!Base || !CodeCompleter) return; - // Peel off the ParenListExpr by chosing the last one, as they don't have a - // predefined type. - 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; @@ -5606,14 +5613,10 @@ ProduceSignatureHelp(Sema &SemaRef, Scope *S, QualType Sema::ProduceCallSignatureHelp(Scope *S, Expr *Fn, ArrayRef<Expr *> Args, SourceLocation OpenParLoc) { + Fn = unwrapParenList(Fn); if (!CodeCompleter || !Fn) return QualType(); - // If we have a ParenListExpr for LHS, peel it off by chosing the last expr. - // As ParenListExprs don't have a predefined type. - 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->isTypeDependent() || anyNullArguments(Args)) _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits