summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2015-02-05 18:56:03 +0000
committerReid Kleckner <reid@kleckner.net>2015-02-05 18:56:03 +0000
commitdeeddeced312a21b8454336cfab9fe2b58863cf8 (patch)
tree87170d3e4cedf4bc76f9916cbdd5d74f33e676e1 /clang/lib
parentc9dd02066cc0528da28bd887e8dbdb3bd9c68165 (diff)
downloadbcm5719-llvm-deeddeced312a21b8454336cfab9fe2b58863cf8.tar.gz
bcm5719-llvm-deeddeced312a21b8454336cfab9fe2b58863cf8.zip
Re-land r228258 and make clang-cl's /EHs- disable -fexceptions again
After r228258, Clang started emitting C++ EH IR that LLVM wasn't ready to deal with, even when exceptions were disabled with /EHs-. This time, make /EHs- turn off -fexceptions while still emitting exceptional constructs in functions using __try. Since Sema rejects C++ exception handling constructs before CodeGen, landingpads should only appear in such functions as the result of a __try. llvm-svn: 228329
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGException.cpp56
-rw-r--r--clang/lib/Driver/Tools.cpp6
-rw-r--r--clang/lib/Sema/SemaStmt.cpp33
3 files changed, 59 insertions, 36 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp
index e148227c39a..5ddd3bbb82b 100644
--- a/clang/lib/CodeGen/CGException.cpp
+++ b/clang/lib/CodeGen/CGException.cpp
@@ -128,7 +128,12 @@ namespace {
// This function must have prototype void(void*).
const char *CatchallRethrowFn;
- static const EHPersonality &get(CodeGenModule &CGM);
+ static const EHPersonality &get(CodeGenModule &CGM,
+ const FunctionDecl *FD);
+ static const EHPersonality &get(CodeGenFunction &CGF) {
+ return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(CGF.CurCodeDecl));
+ }
+
static const EHPersonality GNU_C;
static const EHPersonality GNU_C_SJLJ;
static const EHPersonality GNU_C_SEH;
@@ -141,6 +146,7 @@ namespace {
static const EHPersonality GNU_CPlusPlus_SEH;
static const EHPersonality MSVC_except_handler;
static const EHPersonality MSVC_C_specific_handler;
+ static const EHPersonality MSVC_CxxFrameHandler3;
};
}
@@ -167,6 +173,8 @@ const EHPersonality
EHPersonality::MSVC_except_handler = { "_except_handler3", nullptr };
const EHPersonality
EHPersonality::MSVC_C_specific_handler = { "__C_specific_handler", nullptr };
+const EHPersonality
+EHPersonality::MSVC_CxxFrameHandler3 = { "__CxxFrameHandler3", nullptr };
/// On Win64, use libgcc's SEH personality function. We fall back to dwarf on
/// other platforms, unless the user asked for SjLj exceptions.
@@ -239,35 +247,27 @@ static const EHPersonality &getObjCXXPersonality(const llvm::Triple &T,
llvm_unreachable("bad runtime kind");
}
-static const EHPersonality &getCPersonalityMSVC(const llvm::Triple &T,
- const LangOptions &L) {
- if (L.SjLjExceptions)
- return EHPersonality::GNU_C_SJLJ;
-
+static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) {
if (T.getArch() == llvm::Triple::x86)
return EHPersonality::MSVC_except_handler;
return EHPersonality::MSVC_C_specific_handler;
}
-static const EHPersonality &getCXXPersonalityMSVC(const llvm::Triple &T,
- const LangOptions &L) {
- if (L.SjLjExceptions)
- return EHPersonality::GNU_CPlusPlus_SJLJ;
- // FIXME: Implement C++ exceptions.
- return getCPersonalityMSVC(T, L);
-}
-
-const EHPersonality &EHPersonality::get(CodeGenModule &CGM) {
+const EHPersonality &EHPersonality::get(CodeGenModule &CGM,
+ const FunctionDecl *FD) {
const llvm::Triple &T = CGM.getTarget().getTriple();
const LangOptions &L = CGM.getLangOpts();
+
// Try to pick a personality function that is compatible with MSVC if we're
// not compiling Obj-C. Obj-C users better have an Obj-C runtime that supports
// the GCC-style personality function.
if (T.isWindowsMSVCEnvironment() && !L.ObjC1) {
- if (L.CPlusPlus)
- return getCXXPersonalityMSVC(T, L);
+ if (L.SjLjExceptions)
+ return EHPersonality::GNU_CPlusPlus_SJLJ;
+ else if (FD && FD->usesSEHTry())
+ return getSEHPersonalityMSVC(T);
else
- return getCPersonalityMSVC(T, L);
+ return EHPersonality::MSVC_CxxFrameHandler3;
}
if (L.CPlusPlus && L.ObjC1)
@@ -354,7 +354,7 @@ void CodeGenModule::SimplifyPersonality() {
if (!LangOpts.ObjCRuntime.isNeXTFamily())
return;
- const EHPersonality &ObjCXX = EHPersonality::get(*this);
+ const EHPersonality &ObjCXX = EHPersonality::get(*this, /*FD=*/nullptr);
const EHPersonality &CXX =
getCXXPersonality(getTarget().getTriple(), LangOpts);
if (&ObjCXX == &CXX)
@@ -737,8 +737,16 @@ llvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {
assert(EHStack.requiresLandingPad());
assert(!EHStack.empty());
- if (!CGM.getLangOpts().Exceptions)
- return nullptr;
+ // If exceptions are disabled, there are usually no landingpads. However, when
+ // SEH is enabled, functions using SEH still get landingpads.
+ const LangOptions &LO = CGM.getLangOpts();
+ if (!LO.Exceptions) {
+ if (!LO.Borland && !LO.MicrosoftExt)
+ return nullptr;
+ const auto *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl);
+ if (!FD || !FD->usesSEHTry())
+ return nullptr;
+ }
// Check the innermost scope for a cached landing pad. If this is
// a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.
@@ -778,7 +786,7 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, CurEHLocation);
- const EHPersonality &personality = EHPersonality::get(CGM);
+ const EHPersonality &personality = EHPersonality::get(*this);
// Create and configure the landing pad.
llvm::BasicBlock *lpad = createBasicBlock("lpad");
@@ -1595,7 +1603,7 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
Builder.SetInsertPoint(TerminateLandingPad);
// Tell the backend that this is a landing pad.
- const EHPersonality &Personality = EHPersonality::get(CGM);
+ const EHPersonality &Personality = EHPersonality::get(*this);
llvm::LandingPadInst *LPadInst =
Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr),
getOpaquePersonalityFn(CGM, Personality), 0);
@@ -1654,7 +1662,7 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
EHResumeBlock = createBasicBlock("eh.resume");
Builder.SetInsertPoint(EHResumeBlock);
- const EHPersonality &Personality = EHPersonality::get(CGM);
+ const EHPersonality &Personality = EHPersonality::get(*this);
// This can always be a call because we necessarily didn't find
// anything on the EH stack which needs our help.
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index d24375b3d78..8634ed604c6 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -4877,10 +4877,10 @@ void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
const Driver &D = getToolChain().getDriver();
EHFlags EH = parseClangCLEHFlags(D, Args);
// FIXME: Do something with NoExceptC.
- if (EH.Synch || EH.Asynch)
+ if (EH.Synch || EH.Asynch) {
CmdArgs.push_back("-fcxx-exceptions");
- // Always add -fexceptions to allow SEH __try.
- CmdArgs.push_back("-fexceptions");
+ CmdArgs.push_back("-fexceptions");
+ }
// /EP should expand to -E -P.
if (Args.hasArg(options::OPT__SLASH_EP)) {
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index d17cf227011..4761c32f78d 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3303,11 +3303,12 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())
Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";
+ sema::FunctionScopeInfo *FSI = getCurFunction();
+
// C++ try is incompatible with SEH __try.
- if (!getLangOpts().Borland && getCurFunction()->FirstSEHTryLoc.isValid()) {
+ if (!getLangOpts().Borland && FSI->FirstSEHTryLoc.isValid()) {
Diag(TryLoc, diag::err_mixing_cxx_try_seh_try);
- Diag(getCurFunction()->FirstSEHTryLoc, diag::note_conflicting_try_here)
- << "'__try'";
+ Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'";
}
const unsigned NumHandlers = Handlers.size();
@@ -3352,7 +3353,7 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock,
}
}
- getCurFunction()->setHasCXXTry(TryLoc);
+ FSI->setHasCXXTry(TryLoc);
// FIXME: We should detect handlers that cannot catch anything because an
// earlier handler catches a superclass. Need to find a method that is not
@@ -3367,15 +3368,29 @@ StmtResult Sema::ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc,
Stmt *TryBlock, Stmt *Handler) {
assert(TryBlock && Handler);
+ sema::FunctionScopeInfo *FSI = getCurFunction();
+
// SEH __try is incompatible with C++ try. Borland appears to support this,
// however.
- if (!getLangOpts().Borland && getCurFunction()->FirstCXXTryLoc.isValid()) {
- Diag(TryLoc, diag::err_mixing_cxx_try_seh_try);
- Diag(getCurFunction()->FirstCXXTryLoc, diag::note_conflicting_try_here)
- << "'try'";
+ if (!getLangOpts().Borland) {
+ if (FSI->FirstCXXTryLoc.isValid()) {
+ Diag(TryLoc, diag::err_mixing_cxx_try_seh_try);
+ Diag(FSI->FirstCXXTryLoc, diag::note_conflicting_try_here) << "'try'";
+ }
}
- getCurFunction()->setHasSEHTry(TryLoc);
+ FSI->setHasSEHTry(TryLoc);
+
+ // Reject __try in Obj-C methods, blocks, and captured decls, since we don't
+ // track if they use SEH.
+ DeclContext *DC = CurContext;
+ while (DC && !DC->isFunctionOrMethod())
+ DC = DC->getParent();
+ FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DC);
+ if (FD)
+ FD->setUsesSEHTry(true);
+ else
+ Diag(TryLoc, diag::err_seh_try_outside_functions);
return SEHTryStmt::Create(Context, IsCXXTry, TryLoc, TryBlock, Handler);
}
OpenPOWER on IntegriCloud