summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Lex/Pragma.cpp3
-rw-r--r--clang/tools/driver/driver.cpp22
-rw-r--r--llvm/include/llvm/Support/ManagedStatic.h6
-rw-r--r--llvm/include/llvm/Support/Timer.h5
-rw-r--r--llvm/lib/Support/Timer.cpp4
5 files changed, 33 insertions, 7 deletions
diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
index a8cd18b123b..57a95815488 100644
--- a/clang/lib/Lex/Pragma.cpp
+++ b/clang/lib/Lex/Pragma.cpp
@@ -42,6 +42,7 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Timer.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -1038,6 +1039,8 @@ struct PragmaDebugHandler : public PragmaHandler {
if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
llvm_unreachable("This is an assertion!");
} else if (II->isStr("crash")) {
+ llvm::Timer T("crash", "pragma crash");
+ llvm::TimeRegion R(&T);
if (!PP.getPreprocessorOpts().DisablePragmaDebugCrash)
LLVM_BUILTIN_TRAP;
} else if (II->isStr("parser_crash")) {
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 4457e40ff04..7b3968341cc 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -30,6 +30,7 @@
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
+#include "llvm/Support/BuryPointer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/ErrorHandling.h"
@@ -491,6 +492,7 @@ int main(int argc_, const char **argv_) {
std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));
int Res = 1;
+ bool IsCrash = false;
if (C && !C->containsError()) {
SmallVector<std::pair<int, const Command *>, 4> FailingCommands;
Res = TheDriver.ExecuteCompilation(*C, FailingCommands);
@@ -517,11 +519,11 @@ int main(int argc_, const char **argv_) {
// If result status is 70, then the driver command reported a fatal error.
// On Windows, abort will return an exit code of 3. In these cases,
// generate additional diagnostic information if possible.
- bool DiagnoseCrash = CommandRes < 0 || CommandRes == 70;
+ IsCrash = CommandRes < 0 || CommandRes == 70;
#ifdef _WIN32
- DiagnoseCrash |= CommandRes == 3;
+ IsCrash |= CommandRes == 3;
#endif
- if (DiagnoseCrash) {
+ if (IsCrash) {
TheDriver.generateCompilationDiagnostics(*C, *FailingCommand);
break;
}
@@ -530,10 +532,16 @@ int main(int argc_, const char **argv_) {
Diags.getClient()->finish();
- // If any timers were active but haven't been destroyed yet, print their
- // results now. This happens in -disable-free mode.
- llvm::TimerGroup::printAll(llvm::errs());
- llvm::TimerGroup::clearAll();
+ if (!UseNewCC1Process && IsCrash) {
+ // When crashing in -fintegrated-cc1 mode, bury the timer pointers, because
+ // the internal linked list might point to already released stack frames.
+ llvm::BuryPointer(llvm::TimerGroup::aquireDefaultGroup());
+ } else {
+ // If any timers were active but haven't been destroyed yet, print their
+ // results now. This happens in -disable-free mode.
+ llvm::TimerGroup::printAll(llvm::errs());
+ llvm::TimerGroup::clearAll();
+ }
#ifdef _WIN32
// Exit status should not be negative on Win32, unless abnormal termination.
diff --git a/llvm/include/llvm/Support/ManagedStatic.h b/llvm/include/llvm/Support/ManagedStatic.h
index e65bb051f18..bbd0d04ed04 100644
--- a/llvm/include/llvm/Support/ManagedStatic.h
+++ b/llvm/include/llvm/Support/ManagedStatic.h
@@ -102,6 +102,12 @@ public:
}
const C *operator->() const { return &**this; }
+
+ // Extract the instance, leaving the ManagedStatic uninitialized. The
+ // user is then responsible for the lifetime of the returned instance.
+ C *claim() {
+ return static_cast<C *>(Ptr.exchange(nullptr));
+ }
};
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
diff --git a/llvm/include/llvm/Support/Timer.h b/llvm/include/llvm/Support/Timer.h
index a298ecd9040..045ac448bdb 100644
--- a/llvm/include/llvm/Support/Timer.h
+++ b/llvm/include/llvm/Support/Timer.h
@@ -230,6 +230,11 @@ public:
/// used by the Statistic code to influence the construction and destruction
/// order of the global timer lists.
static void ConstructTimerLists();
+
+ /// This makes the default group unmanaged, and lets the user manage the
+ /// group's lifetime.
+ static std::unique_ptr<TimerGroup> aquireDefaultGroup();
+
private:
friend class Timer;
friend void PrintStatisticsJSON(raw_ostream &OS);
diff --git a/llvm/lib/Support/Timer.cpp b/llvm/lib/Support/Timer.cpp
index 613d2eaae6d..2d3d0081282 100644
--- a/llvm/lib/Support/Timer.cpp
+++ b/llvm/lib/Support/Timer.cpp
@@ -441,3 +441,7 @@ const char *TimerGroup::printAllJSONValues(raw_ostream &OS, const char *delim) {
void TimerGroup::ConstructTimerLists() {
(void)*NamedGroupedTimers;
}
+
+std::unique_ptr<TimerGroup> TimerGroup::aquireDefaultGroup() {
+ return std::unique_ptr<TimerGroup>(DefaultTimerGroup.claim());
+}
OpenPOWER on IntegriCloud