summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/ExpectedTypes.cpp4
-rw-r--r--clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp11
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp3
-rw-r--r--clang/test/CodeCompletion/crash-null-type.cpp8
4 files changed, 24 insertions, 2 deletions
diff --git a/clang-tools-extra/clangd/ExpectedTypes.cpp b/clang-tools-extra/clangd/ExpectedTypes.cpp
index 4bbf0651260..59d9e149162 100644
--- a/clang-tools-extra/clangd/ExpectedTypes.cpp
+++ b/clang-tools-extra/clangd/ExpectedTypes.cpp
@@ -35,8 +35,10 @@ static llvm::Optional<QualType>
typeOfCompletion(const CodeCompletionResult &R) {
auto *VD = dyn_cast_or_null<ValueDecl>(R.Declaration);
if (!VD)
- return None; // We handle only variables and functions below.
+ return llvm::None; // We handle only variables and functions below.
auto T = VD->getType();
+ if (T.isNull())
+ return llvm::None;
if (auto FuncT = T->getAs<FunctionType>()) {
// Functions are a special case. They are completed as 'foo()' and we want
// to match their return type rather than the function type itself.
diff --git a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
index c80593443ff..16d5eef0fbb 100644
--- a/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
+++ b/clang-tools-extra/unittests/clangd/CodeCompleteTests.cpp
@@ -2319,6 +2319,17 @@ TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) {
EXPECT_THAT(C, ElementsAre(SnippetSuffix("${1:(unsigned int)}")));
}
+TEST(CompletionTest, WorksWithNullType) {
+ auto R = completions(R"cpp(
+ int main() {
+ for (auto [loopVar] : y ) { // y has to be unresolved.
+ int z = loopV^;
+ }
+ }
+ )cpp");
+ EXPECT_THAT(R.Completions, ElementsAre(Named("loopVar")));
+}
+
} // namespace
} // namespace clangd
} // namespace clang
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index ab18d7fb5e0..9bed545a528 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -680,7 +680,8 @@ QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
T = Property->getType();
else if (const auto *Value = dyn_cast<ValueDecl>(ND))
T = Value->getType();
- else
+
+ if (T.isNull())
return QualType();
// Dig through references, function pointers, and block pointers to
diff --git a/clang/test/CodeCompletion/crash-null-type.cpp b/clang/test/CodeCompletion/crash-null-type.cpp
new file mode 100644
index 00000000000..c5b3d1e7939
--- /dev/null
+++ b/clang/test/CodeCompletion/crash-null-type.cpp
@@ -0,0 +1,8 @@
+void test() {
+ for (auto [loopVar] : y) { // y has to be unresolved
+ loopVa
+ }
+}
+// RUN: not %clang_cc1 -fsyntax-only -code-completion-at=%s:3:11 %s -o - \
+// RUN: | FileCheck %s
+// CHECK: COMPLETION: loopVar
OpenPOWER on IntegriCloud