Index: clang-tools-extra/trunk/clangd/Selection.cpp =================================================================== --- clang-tools-extra/trunk/clangd/Selection.cpp +++ clang-tools-extra/trunk/clangd/Selection.cpp @@ -358,13 +358,10 @@ const Node *SelectionTree::commonAncestor() const { if (!Root) return nullptr; - for (const Node *Ancestor = Root;; Ancestor = Ancestor->Children.front()) { - if (Ancestor->Selected || Ancestor->Children.size() > 1) - return Ancestor; - // The tree only contains ancestors of the interesting nodes. - assert(!Ancestor->Children.empty() && "bad node in selection tree"); - } - return nullptr; + const Node *Ancestor = Root; + while (Ancestor->Children.size() == 1 && !Ancestor->Selected) + Ancestor = Ancestor->Children.front(); + return Ancestor; } } // namespace clangd Index: clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractVariable.cpp =================================================================== --- clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractVariable.cpp +++ clang-tools-extra/trunk/clangd/refactor/tweaks/ExtractVariable.cpp @@ -81,7 +81,7 @@ // FIXME: Ignore assignment (a = 1) Expr since it is extracted as dummy = a = static bool isExtractableExpr(const clang::Expr *Expr) { if (Expr) { - const Type *ExprType = Expr->getType().getTypePtr(); + const Type *ExprType = Expr->getType().getTypePtrOrNull(); // FIXME: check if we need to cover any other types if (ExprType) return !ExprType->isVoidType(); Index: clang-tools-extra/trunk/clangd/unittests/TweakTests.cpp =================================================================== --- clang-tools-extra/trunk/clangd/unittests/TweakTests.cpp +++ clang-tools-extra/trunk/clangd/unittests/TweakTests.cpp @@ -313,6 +313,14 @@ while(a < ^3); } )cpp"); + // Should not crash. + checkNotAvailable(ID, R"cpp( + template + struct Test { + Test(const T &v) :val(^) {} + T val; + }; + )cpp"); checkNotAvailable(ID, R"cpp( int xyz(int a = ^1) { return 1;