From eb90c50caad3534dde4f709ec833a07f29ae97e4 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Thu, 5 Feb 2015 02:08:50 +0000 Subject: [PATCH] Revert r228258. It caused a chromium base unittest that tests throwing and catching SEH exceptions to fail (http://crbug.com/455488) and I suspect it might also be the cause of the chromium clang win 64-bit shared release builder timing out during compiles. So revert to see if that's true. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@228262 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Decl.h | 11 +--- include/clang/Basic/DiagnosticSemaKinds.td | 2 - lib/CodeGen/CGException.cpp | 44 ++++++------- lib/Sema/SemaStmt.cpp | 33 +++------- test/CodeGenCXX/exceptions-seh.cpp | 76 ---------------------- test/SemaCXX/exceptions-seh.cpp | 47 +------------ 6 files changed, 34 insertions(+), 179 deletions(-) delete mode 100644 test/CodeGenCXX/exceptions-seh.cpp diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 84ed2862f3..4580cba113 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1482,9 +1482,6 @@ private: bool IsLateTemplateParsed : 1; bool IsConstexpr : 1; - /// \brief Indicates if the function uses __try. - bool UsesSEHTry : 1; - /// \brief Indicates if the function was a definition but its body was /// skipped. unsigned HasSkippedBody : 1; @@ -1573,8 +1570,8 @@ protected: HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), IsDefaulted(false), IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), IsLateTemplateParsed(false), - IsConstexpr(isConstexprSpecified), UsesSEHTry(false), - HasSkippedBody(false), EndRangeLoc(NameInfo.getEndLoc()), + IsConstexpr(isConstexprSpecified), HasSkippedBody(false), + EndRangeLoc(NameInfo.getEndLoc()), TemplateOrSpecialization(), DNLoc(NameInfo.getInfo()) {} @@ -1754,10 +1751,6 @@ public: bool isConstexpr() const { return IsConstexpr; } void setConstexpr(bool IC) { IsConstexpr = IC; } - /// Whether this is a (C++11) constexpr function or constexpr constructor. - bool usesSEHTry() const { return UsesSEHTry; } - void setUsesSEHTry(bool UST) { UsesSEHTry = UST; } - /// \brief Whether this function has been deleted. /// /// A function that is "deleted" (via the C++0x "= delete" syntax) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5c66952979..4f68d10135 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -5466,8 +5466,6 @@ def err_exceptions_disabled : Error< "cannot use '%0' with exceptions disabled">; def err_objc_exceptions_disabled : Error< "cannot use '%0' with Objective-C exceptions disabled">; -def err_seh_try_outside_functions : Error< - "cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls">; def err_mixing_cxx_try_seh_try : Error< "cannot use C++ 'try' in the same function as SEH '__try'">; def note_conflicting_try_here : Note< diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp index 7373ed6ea6..e148227c39 100644 --- a/lib/CodeGen/CGException.cpp +++ b/lib/CodeGen/CGException.cpp @@ -128,12 +128,7 @@ namespace { // This function must have prototype void(void*). const char *CatchallRethrowFn; - static const EHPersonality &get(CodeGenModule &CGM, - const FunctionDecl *FD); - static const EHPersonality &get(CodeGenFunction &CGF) { - return get(CGF.CGM, dyn_cast_or_null(CGF.CurCodeDecl)); - } - + static const EHPersonality &get(CodeGenModule &CGM); static const EHPersonality GNU_C; static const EHPersonality GNU_C_SJLJ; static const EHPersonality GNU_C_SEH; @@ -146,7 +141,6 @@ 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; }; } @@ -173,8 +167,6 @@ 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. @@ -247,27 +239,35 @@ static const EHPersonality &getObjCXXPersonality(const llvm::Triple &T, llvm_unreachable("bad runtime kind"); } -static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) { +static const EHPersonality &getCPersonalityMSVC(const llvm::Triple &T, + const LangOptions &L) { + if (L.SjLjExceptions) + return EHPersonality::GNU_C_SJLJ; + if (T.getArch() == llvm::Triple::x86) return EHPersonality::MSVC_except_handler; return EHPersonality::MSVC_C_specific_handler; } -const EHPersonality &EHPersonality::get(CodeGenModule &CGM, - const FunctionDecl *FD) { +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 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.SjLjExceptions) - return EHPersonality::GNU_CPlusPlus_SJLJ; - else if (FD && FD->usesSEHTry()) - return getSEHPersonalityMSVC(T); + if (L.CPlusPlus) + return getCXXPersonalityMSVC(T, L); else - return EHPersonality::MSVC_CxxFrameHandler3; + return getCPersonalityMSVC(T, L); } if (L.CPlusPlus && L.ObjC1) @@ -354,7 +354,7 @@ void CodeGenModule::SimplifyPersonality() { if (!LangOpts.ObjCRuntime.isNeXTFamily()) return; - const EHPersonality &ObjCXX = EHPersonality::get(*this, /*FD=*/nullptr); + const EHPersonality &ObjCXX = EHPersonality::get(*this); const EHPersonality &CXX = getCXXPersonality(getTarget().getTriple(), LangOpts); if (&ObjCXX == &CXX) @@ -778,7 +778,7 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() { CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP(); auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, CurEHLocation); - const EHPersonality &personality = EHPersonality::get(*this); + const EHPersonality &personality = EHPersonality::get(CGM); // Create and configure the landing pad. llvm::BasicBlock *lpad = createBasicBlock("lpad"); @@ -1595,7 +1595,7 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() { Builder.SetInsertPoint(TerminateLandingPad); // Tell the backend that this is a landing pad. - const EHPersonality &Personality = EHPersonality::get(*this); + const EHPersonality &Personality = EHPersonality::get(CGM); llvm::LandingPadInst *LPadInst = Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr), getOpaquePersonalityFn(CGM, Personality), 0); @@ -1654,7 +1654,7 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) { EHResumeBlock = createBasicBlock("eh.resume"); Builder.SetInsertPoint(EHResumeBlock); - const EHPersonality &Personality = EHPersonality::get(*this); + const EHPersonality &Personality = EHPersonality::get(CGM); // This can always be a call because we necessarily didn't find // anything on the EH stack which needs our help. diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 4761c32f78..d17cf22701 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -3303,12 +3303,11 @@ 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 && FSI->FirstSEHTryLoc.isValid()) { + if (!getLangOpts().Borland && getCurFunction()->FirstSEHTryLoc.isValid()) { Diag(TryLoc, diag::err_mixing_cxx_try_seh_try); - Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'"; + Diag(getCurFunction()->FirstSEHTryLoc, diag::note_conflicting_try_here) + << "'__try'"; } const unsigned NumHandlers = Handlers.size(); @@ -3353,7 +3352,7 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, } } - FSI->setHasCXXTry(TryLoc); + getCurFunction()->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 @@ -3368,29 +3367,15 @@ 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) { - if (FSI->FirstCXXTryLoc.isValid()) { - Diag(TryLoc, diag::err_mixing_cxx_try_seh_try); - Diag(FSI->FirstCXXTryLoc, diag::note_conflicting_try_here) << "'try'"; - } + if (!getLangOpts().Borland && getCurFunction()->FirstCXXTryLoc.isValid()) { + Diag(TryLoc, diag::err_mixing_cxx_try_seh_try); + Diag(getCurFunction()->FirstCXXTryLoc, diag::note_conflicting_try_here) + << "'try'"; } - 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(DC); - if (FD) - FD->setUsesSEHTry(true); - else - Diag(TryLoc, diag::err_seh_try_outside_functions); + getCurFunction()->setHasSEHTry(TryLoc); return SEHTryStmt::Create(Context, IsCXXTry, TryLoc, TryBlock, Handler); } diff --git a/test/CodeGenCXX/exceptions-seh.cpp b/test/CodeGenCXX/exceptions-seh.cpp deleted file mode 100644 index 74b43a94f6..0000000000 --- a/test/CodeGenCXX/exceptions-seh.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm -o - -fcxx-exceptions -fexceptions -mconstructor-aliases | FileCheck %s - -extern "C" void might_throw(); - -struct HasCleanup { - HasCleanup(); - ~HasCleanup(); - int padding; -}; - -extern "C" void use_cxx() { - HasCleanup x; - might_throw(); -} - -// Make sure we use __CxxFrameHandler3 for C++ EH. - -// CHECK-LABEL: define void @use_cxx() -// CHECK: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) -// CHECK: invoke void @might_throw() -// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] -// -// CHECK: [[cont]] -// CHECK: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) -// CHECK: ret void -// -// CHECK: [[lpad]] -// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) -// CHECK-NEXT: cleanup -// CHECK: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) -// CHECK: br label %[[resume:[^ ]*]] -// -// CHECK: [[resume]] -// CHECK: resume - -extern "C" void use_seh() { - __try { - might_throw(); - } __except(1) { - } -} - -// Make sure we use __C_specific_handler for SEH. - -// CHECK-LABEL: define void @use_seh() -// CHECK: invoke void @might_throw() -// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] -// -// CHECK: [[cont]] -// CHECK: br label %[[ret:[^ ]*]] -// -// CHECK: [[lpad]] -// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) -// CHECK-NEXT: catch i8* -// -// CHECK: br label %[[ret]] -// -// CHECK: [[ret]] -// CHECK: ret void - -void use_seh_in_lambda() { - ([]() { - __try { - might_throw(); - } __except(1) { - } - })(); - HasCleanup x; - might_throw(); -} - -// CHECK-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"() -// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) - -// CHECK-LABEL: define internal void @"\01??R@?use_seh_in_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this) -// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) diff --git a/test/SemaCXX/exceptions-seh.cpp b/test/SemaCXX/exceptions-seh.cpp index 7375ec9bf8..dd00c11590 100644 --- a/test/SemaCXX/exceptions-seh.cpp +++ b/test/SemaCXX/exceptions-seh.cpp @@ -1,5 +1,4 @@ -// RUN: %clang_cc1 -std=c++03 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s -// RUN: %clang_cc1 -std=c++11 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s // Basic usage should work. int safe_div(int n, int d) { @@ -38,7 +37,6 @@ void instantiate_bad_scope_tmpl() { bad_builtin_scope_template(); } -#if __cplusplus < 201103L // FIXME: Diagnose this case. For now we produce undef in codegen. template T func_template() { @@ -48,7 +46,6 @@ void inject_builtins() { func_template(); func_template(); } -#endif void use_seh_after_cxx() { try { // expected-note {{conflicting 'try' here}} @@ -71,45 +68,3 @@ void use_cxx_after_seh() { } catch (int) { } } - -#if __cplusplus >= 201103L -void use_seh_in_lambda() { - ([]() { - __try { - might_crash(); - } __except(1) { - } - })(); - try { - might_crash(); - } catch (int) { - } -} -#endif - -void use_seh_in_block() { - void (^b)() = ^{ - __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}} - might_crash(); - } __except(1) { - } - }; - try { - b(); - } catch (int) { - } -} - -void (^use_seh_in_global_block)() = ^{ - __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}} - might_crash(); - } __except(1) { - } -}; - -void (^use_cxx_in_global_block)() = ^{ - try { - might_crash(); - } catch(int) { - } -}; -- 2.40.0