Initialize the non-target-dependent fields of the Preprocessor in its constructor
so we can destroy it even if it was constructed with "DelayInitialization = true",
and we didn't end up calling Preprocessor::Initialize.
Fixes crashes in rdar://11558355
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@157892 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 06e5685..d387f43 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -66,54 +66,6 @@
Record(0), MIChainHead(0), MICache(0)
{
OwnsHeaderSearch = OwnsHeaders;
-
- if (!DelayInitialization) {
- assert(Target && "Must provide target information for PP initialization");
- Initialize(*Target);
- }
-}
-
-Preprocessor::~Preprocessor() {
- assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!");
-
- while (!IncludeMacroStack.empty()) {
- delete IncludeMacroStack.back().TheLexer;
- delete IncludeMacroStack.back().TheTokenLexer;
- IncludeMacroStack.pop_back();
- }
-
- // Free any macro definitions.
- for (MacroInfoChain *I = MIChainHead ; I ; I = I->Next)
- I->MI.Destroy();
-
- // Free any cached macro expanders.
- for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i)
- delete TokenLexerCache[i];
-
- // Free any cached MacroArgs.
- for (MacroArgs *ArgList = MacroArgCache; ArgList; )
- ArgList = ArgList->deallocate();
-
- // Release pragma information.
- delete PragmaHandlers;
-
- // Delete the scratch buffer info.
- delete ScratchBuf;
-
- // Delete the header search info, if we own it.
- if (OwnsHeaderSearch)
- delete &HeaderInfo;
-
- delete Callbacks;
-}
-
-void Preprocessor::Initialize(const TargetInfo &Target) {
- assert((!this->Target || this->Target == &Target) &&
- "Invalid override of target information");
- this->Target = &Target;
-
- // Initialize information about built-ins.
- BuiltinInfo.InitializeTarget(Target);
ScratchBuf = new ScratchBuffer(SourceMgr);
CounterValue = 0; // __COUNTER__ starts at 0.
@@ -170,7 +122,54 @@
Ident___exception_info = Ident___exception_code = Ident___abnormal_termination = 0;
Ident_GetExceptionInfo = Ident_GetExceptionCode = Ident_AbnormalTermination = 0;
}
+
+ if (!DelayInitialization) {
+ assert(Target && "Must provide target information for PP initialization");
+ Initialize(*Target);
+ }
+}
+
+Preprocessor::~Preprocessor() {
+ assert(BacktrackPositions.empty() && "EnableBacktrack/Backtrack imbalance!");
+
+ while (!IncludeMacroStack.empty()) {
+ delete IncludeMacroStack.back().TheLexer;
+ delete IncludeMacroStack.back().TheTokenLexer;
+ IncludeMacroStack.pop_back();
+ }
+
+ // Free any macro definitions.
+ for (MacroInfoChain *I = MIChainHead ; I ; I = I->Next)
+ I->MI.Destroy();
+
+ // Free any cached macro expanders.
+ for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i)
+ delete TokenLexerCache[i];
+
+ // Free any cached MacroArgs.
+ for (MacroArgs *ArgList = MacroArgCache; ArgList; )
+ ArgList = ArgList->deallocate();
+
+ // Release pragma information.
+ delete PragmaHandlers;
+
+ // Delete the scratch buffer info.
+ delete ScratchBuf;
+
+ // Delete the header search info, if we own it.
+ if (OwnsHeaderSearch)
+ delete &HeaderInfo;
+
+ delete Callbacks;
+}
+
+void Preprocessor::Initialize(const TargetInfo &Target) {
+ assert((!this->Target || this->Target == &Target) &&
+ "Invalid override of target information");
+ this->Target = &Target;
+ // Initialize information about built-ins.
+ BuiltinInfo.InitializeTarget(Target);
HeaderInfo.setTarget(Target);
}
diff --git a/test/Index/create-tu-fail.c b/test/Index/create-tu-fail.c
new file mode 100644
index 0000000..3241e14
--- /dev/null
+++ b/test/Index/create-tu-fail.c
@@ -0,0 +1,10 @@
+// RUN: rm %t.c
+// RUN: touch %t.c
+// RUN: c-index-test -write-pch %t.pch %t.c
+// RUN: cp %s %t.c
+// RUN: c-index-test -test-load-tu %t.pch local 2>&1 | FileCheck %s
+
+// rdar://11558355
+// Unfortunately this would crash reliably only via valgrind.
+
+// CHECK: Unable to load translation unit