]> granicus.if.org Git - clang/commitdiff
Avoid a crash after loading an #undef'd macro in code completion
authorBen Langmuir <blangmuir@apple.com>
Tue, 30 Sep 2014 20:00:18 +0000 (20:00 +0000)
committerBen Langmuir <blangmuir@apple.com>
Tue, 30 Sep 2014 20:00:18 +0000 (20:00 +0000)
In code-completion, don't assume there is a MacroInfo for everything,
since we aren't serializing the def corresponding to a later #undef in
the same module.  Also setup the HadMacro bit correctly for undefs to
avoid an assertion failure.

rdar://18416901

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218694 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Lex/PPMacroExpansion.cpp
lib/Sema/SemaCodeComplete.cpp
test/Index/Inputs/module-undef.h [new file with mode: 0644]
test/Index/Inputs/module.map
test/Index/complete-module-undef.m [new file with mode: 0644]

index 62d2da56ba97e9c0ff3a62f1103e91111a3b7351..e875860f820b6fd76d89c6f1f5b607375d876b5f 100644 (file)
@@ -49,7 +49,10 @@ void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
   MacroDirective *&StoredMD = Macros[II];
   MD->setPrevious(StoredMD);
   StoredMD = MD;
-  II->setHasMacroDefinition(MD->isDefined());
+  // Setup the identifier as having associated macro history.
+  II->setHasMacroDefinition(true);
+  if (!MD->isDefined())
+    II->setHasMacroDefinition(false);
   bool isImportedMacro = isa<DefMacroDirective>(MD) &&
                          cast<DefMacroDirective>(MD)->isImported();
   if (II->isFromAST() && !isImportedMacro)
index 3d250e3bef1158ee8c4808b35fbb72cef521ec07..10b243cd509d1b042f6e1b9f86ff35f29a542344 100644 (file)
@@ -2575,11 +2575,12 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
     const MacroDirective *MD = PP.getMacroDirectiveHistory(Macro);
     assert(MD && "Not a macro?");
     const MacroInfo *MI = MD->getMacroInfo();
+    assert((!MD->isDefined() || MI) && "missing MacroInfo for define");
 
     Result.AddTypedTextChunk(
                             Result.getAllocator().CopyString(Macro->getName()));
 
-    if (!MI->isFunctionLike())
+    if (!MI || !MI->isFunctionLike())
       return Result.TakeString();
     
     // Format a function-like macro with placeholders for the arguments.
diff --git a/test/Index/Inputs/module-undef.h b/test/Index/Inputs/module-undef.h
new file mode 100644 (file)
index 0000000..8212d75
--- /dev/null
@@ -0,0 +1,2 @@
+#define MY_MACRO 1
+#undef MY_MACRO
index 8f24840c81f9a6593571aa15bf8033cd43ec2fb5..4bfc109a8b1361e5790360c4620e1ceff0e9b427 100644 (file)
@@ -4,3 +4,5 @@ module ModuleNeedsVFS {
   export *
 }
 framework module * { }
+
+module ModuleUndef { header "module-undef.h" }
diff --git a/test/Index/complete-module-undef.m b/test/Index/complete-module-undef.m
new file mode 100644 (file)
index 0000000..a9dd000
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: env CINDEXTEST_COMPLETION_CACHING=1 \
+// RUN:     c-index-test -test-load-source-reparse 2 local %s -fmodules -fmodules-cache-path=%t -I %S/Inputs \
+// RUN:   | FileCheck %s
+
+// rdar://18416901 (used to crash)
+// CHECK: complete-module-undef.m:8:1: ModuleImport=ModuleUndef:8:1 (Definition) Extent=[8:1 - 8:20]
+@import ModuleUndef;