<p dir="ltr">Interesting.  Any idea why?  The -O0 flag is explicitly passed, isn't it?</p>
<br><div class="gmail_quote">пт, 6 февр. 2015, 21:50, Reid Kleckner <<a href="mailto:rnk@google.com">rnk@google.com</a>>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">It passes for me locally in debug but not release.</div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 5, 2015 at 9:04 PM, Nico Weber <span dir="ltr"><<a href="mailto:thakis@chromium.org" target="_blank">thakis@chromium.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">WrappedWindowProc.CatchesExceptions started failing again on all 64-bit chromium bots, with a regression range of r228301:228332. Probably this change again?<br></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 5, 2015 at 10:56 AM, Reid Kleckner <span dir="ltr"><<a href="mailto:reid@kleckner.net" target="_blank">reid@kleckner.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Thu Feb  5 12:56:03 2015<br>
New Revision: 228329<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=228329&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=228329&view=rev</a><br>
Log:<br>
Re-land r228258 and make clang-cl's /EHs- disable -fexceptions again<br>
<br>
After r228258, Clang started emitting C++ EH IR that LLVM wasn't ready<br>
to deal with, even when exceptions were disabled with /EHs-. This time,<br>
make /EHs- turn off -fexceptions while still emitting exceptional<br>
constructs in functions using __try.  Since Sema rejects C++ exception<br>
handling constructs before CodeGen, landingpads should only appear in<br>
such functions as the result of a __try.<br>
<br>
Added:<br>
    cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/AST/Decl.h<br>
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
    cfe/trunk/lib/CodeGen/CGException.cpp<br>
    cfe/trunk/lib/Driver/Tools.cpp<br>
    cfe/trunk/lib/Sema/SemaStmt.cpp<br>
    cfe/trunk/test/CodeGen/exceptions-seh-finally.c<br>
    cfe/trunk/test/CodeGen/exceptions-seh-leave.c<br>
    cfe/trunk/test/CodeGen/exceptions-seh.c<br>
    cfe/trunk/test/Driver/cl-eh.cpp<br>
    cfe/trunk/test/SemaCXX/exceptions-seh.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/Decl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=228329&r1=228328&r2=228329&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=228329&r1=228328&r2=228329&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/Decl.h (original)<br>
+++ cfe/trunk/include/clang/AST/Decl.h Thu Feb  5 12:56:03 2015<br>
@@ -1482,6 +1482,9 @@ private:<br>
   bool IsLateTemplateParsed : 1;<br>
   bool IsConstexpr : 1;<br>
<br>
+  /// \brief Indicates if the function uses __try.<br>
+  bool UsesSEHTry : 1;<br>
+<br>
   /// \brief Indicates if the function was a definition but its body was<br>
   /// skipped.<br>
   unsigned HasSkippedBody : 1;<br>
@@ -1570,8 +1573,8 @@ protected:<br>
       HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false),<br>
       IsDefaulted(false), IsExplicitlyDefaulted(false),<br>
       HasImplicitReturnZero(false), IsLateTemplateParsed(false),<br>
-      IsConstexpr(isConstexprSpecified), HasSkippedBody(false),<br>
-      EndRangeLoc(NameInfo.getEndLoc()),<br>
+      IsConstexpr(isConstexprSpecified), UsesSEHTry(false),<br>
+      HasSkippedBody(false), EndRangeLoc(NameInfo.getEndLoc()),<br>
       TemplateOrSpecialization(),<br>
       DNLoc(NameInfo.getInfo()) {}<br>
<br>
@@ -1751,6 +1754,10 @@ public:<br>
   bool isConstexpr() const { return IsConstexpr; }<br>
   void setConstexpr(bool IC) { IsConstexpr = IC; }<br>
<br>
+  /// Whether this is a (C++11) constexpr function or constexpr constructor.<br>
+  bool usesSEHTry() const { return UsesSEHTry; }<br>
+  void setUsesSEHTry(bool UST) { UsesSEHTry = UST; }<br>
+<br>
   /// \brief Whether this function has been deleted.<br>
   ///<br>
   /// A function that is "deleted" (via the C++0x "= delete" syntax)<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=228329&r1=228328&r2=228329&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=228329&r1=228328&r2=228329&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Feb  5 12:56:03 2015<br>
@@ -5466,6 +5466,8 @@ def err_exceptions_disabled : Error<<br>
   "cannot use '%0' with exceptions disabled">;<br>
 def err_objc_exceptions_disabled : Error<<br>
   "cannot use '%0' with Objective-C exceptions disabled">;<br>
+def err_seh_try_outside_functions : Error<<br>
+  "cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls">;<br>
 def err_mixing_cxx_try_seh_try : Error<<br>
   "cannot use C++ 'try' in the same function as SEH '__try'">;<br>
 def note_conflicting_try_here : Note<<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGException.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=228329&r1=228328&r2=228329&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGException.cpp?rev=228329&r1=228328&r2=228329&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGException.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGException.cpp Thu Feb  5 12:56:03 2015<br>
@@ -128,7 +128,12 @@ namespace {<br>
     // This function must have prototype void(void*).<br>
     const char *CatchallRethrowFn;<br>
<br>
-    static const EHPersonality &get(CodeGenModule &CGM);<br>
+    static const EHPersonality &get(CodeGenModule &CGM,<br>
+                                    const FunctionDecl *FD);<br>
+    static const EHPersonality &get(CodeGenFunction &CGF) {<br>
+      return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(CGF.CurCodeDecl));<br>
+    }<br>
+<br>
     static const EHPersonality GNU_C;<br>
     static const EHPersonality GNU_C_SJLJ;<br>
     static const EHPersonality GNU_C_SEH;<br>
@@ -141,6 +146,7 @@ namespace {<br>
     static const EHPersonality GNU_CPlusPlus_SEH;<br>
     static const EHPersonality MSVC_except_handler;<br>
     static const EHPersonality MSVC_C_specific_handler;<br>
+    static const EHPersonality MSVC_CxxFrameHandler3;<br>
   };<br>
 }<br>
<br>
@@ -167,6 +173,8 @@ const EHPersonality<br>
 EHPersonality::MSVC_except_handler = { "_except_handler3", nullptr };<br>
 const EHPersonality<br>
 EHPersonality::MSVC_C_specific_handler = { "__C_specific_handler", nullptr };<br>
+const EHPersonality<br>
+EHPersonality::MSVC_CxxFrameHandler3 = { "__CxxFrameHandler3", nullptr };<br>
<br>
 /// On Win64, use libgcc's SEH personality function. We fall back to dwarf on<br>
 /// other platforms, unless the user asked for SjLj exceptions.<br>
@@ -239,35 +247,27 @@ static const EHPersonality &getObjCXXPer<br>
   llvm_unreachable("bad runtime kind");<br>
 }<br>
<br>
-static const EHPersonality &getCPersonalityMSVC(const llvm::Triple &T,<br>
-                                                const LangOptions &L) {<br>
-  if (L.SjLjExceptions)<br>
-    return EHPersonality::GNU_C_SJLJ;<br>
-<br>
+static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) {<br>
   if (T.getArch() == llvm::Triple::x86)<br>
     return EHPersonality::MSVC_except_handler;<br>
   return EHPersonality::MSVC_C_specific_handler;<br>
 }<br>
<br>
-static const EHPersonality &getCXXPersonalityMSVC(const llvm::Triple &T,<br>
-                                                  const LangOptions &L) {<br>
-  if (L.SjLjExceptions)<br>
-    return EHPersonality::GNU_CPlusPlus_SJLJ;<br>
-  // FIXME: Implement C++ exceptions.<br>
-  return getCPersonalityMSVC(T, L);<br>
-}<br>
-<br>
-const EHPersonality &EHPersonality::get(CodeGenModule &CGM) {<br>
+const EHPersonality &EHPersonality::get(CodeGenModule &CGM,<br>
+                                        const FunctionDecl *FD) {<br>
   const llvm::Triple &T = CGM.getTarget().getTriple();<br>
   const LangOptions &L = CGM.getLangOpts();<br>
+<br>
   // Try to pick a personality function that is compatible with MSVC if we're<br>
   // not compiling Obj-C. Obj-C users better have an Obj-C runtime that supports<br>
   // the GCC-style personality function.<br>
   if (T.isWindowsMSVCEnvironment() && !L.ObjC1) {<br>
-    if (L.CPlusPlus)<br>
-      return getCXXPersonalityMSVC(T, L);<br>
+    if (L.SjLjExceptions)<br>
+      return EHPersonality::GNU_CPlusPlus_SJLJ;<br>
+    else if (FD && FD->usesSEHTry())<br>
+      return getSEHPersonalityMSVC(T);<br>
     else<br>
-      return getCPersonalityMSVC(T, L);<br>
+      return EHPersonality::MSVC_CxxFrameHandler3;<br>
   }<br>
<br>
   if (L.CPlusPlus && L.ObjC1)<br>
@@ -354,7 +354,7 @@ void CodeGenModule::SimplifyPersonality(<br>
   if (!LangOpts.ObjCRuntime.isNeXTFamily())<br>
     return;<br>
<br>
-  const EHPersonality &ObjCXX = EHPersonality::get(*this);<br>
+  const EHPersonality &ObjCXX = EHPersonality::get(*this, /*FD=*/nullptr);<br>
   const EHPersonality &CXX =<br>
       getCXXPersonality(getTarget().getTriple(), LangOpts);<br>
   if (&ObjCXX == &CXX)<br>
@@ -737,8 +737,16 @@ llvm::BasicBlock *CodeGenFunction::getIn<br>
   assert(EHStack.requiresLandingPad());<br>
   assert(!EHStack.empty());<br>
<br>
-  if (!CGM.getLangOpts().Exceptions)<br>
-    return nullptr;<br>
+  // If exceptions are disabled, there are usually no landingpads. However, when<br>
+  // SEH is enabled, functions using SEH still get landingpads.<br>
+  const LangOptions &LO = CGM.getLangOpts();<br>
+  if (!LO.Exceptions) {<br>
+    if (!LO.Borland && !LO.MicrosoftExt)<br>
+      return nullptr;<br>
+    const auto *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl);<br>
+    if (!FD || !FD->usesSEHTry())<br>
+      return nullptr;<br>
+  }<br>
<br>
   // Check the innermost scope for a cached landing pad.  If this is<br>
   // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.<br>
@@ -778,7 +786,7 @@ llvm::BasicBlock *CodeGenFunction::EmitL<br>
   CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();<br>
   auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, CurEHLocation);<br>
<br>
-  const EHPersonality &personality = EHPersonality::get(CGM);<br>
+  const EHPersonality &personality = EHPersonality::get(*this);<br>
<br>
   // Create and configure the landing pad.<br>
   llvm::BasicBlock *lpad = createBasicBlock("lpad");<br>
@@ -1595,7 +1603,7 @@ llvm::BasicBlock *CodeGenFunction::getTe<br>
   Builder.SetInsertPoint(TerminateLandingPad);<br>
<br>
   // Tell the backend that this is a landing pad.<br>
-  const EHPersonality &Personality = EHPersonality::get(CGM);<br>
+  const EHPersonality &Personality = EHPersonality::get(*this);<br>
   llvm::LandingPadInst *LPadInst =<br>
     Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr),<br>
                              getOpaquePersonalityFn(CGM, Personality), 0);<br>
@@ -1654,7 +1662,7 @@ llvm::BasicBlock *CodeGenFunction::getEH<br>
   EHResumeBlock = createBasicBlock("eh.resume");<br>
   Builder.SetInsertPoint(EHResumeBlock);<br>
<br>
-  const EHPersonality &Personality = EHPersonality::get(CGM);<br>
+  const EHPersonality &Personality = EHPersonality::get(*this);<br>
<br>
   // This can always be a call because we necessarily didn't find<br>
   // anything on the EH stack which needs our help.<br>
<br>
Modified: cfe/trunk/lib/Driver/Tools.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=228329&r1=228328&r2=228329&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=228329&r1=228328&r2=228329&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Driver/Tools.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Tools.cpp Thu Feb  5 12:56:03 2015<br>
@@ -4877,10 +4877,10 @@ void Clang::AddClangCLArgs(const ArgList<br>
   const Driver &D = getToolChain().getDriver();<br>
   EHFlags EH = parseClangCLEHFlags(D, Args);<br>
   // FIXME: Do something with NoExceptC.<br>
-  if (EH.Synch || EH.Asynch)<br>
+  if (EH.Synch || EH.Asynch) {<br>
     CmdArgs.push_back("-fcxx-exceptions");<br>
-  // Always add -fexceptions to allow SEH __try.<br>
-  CmdArgs.push_back("-fexceptions");<br>
+    CmdArgs.push_back("-fexceptions");<br>
+  }<br>
<br>
   // /EP should expand to -E -P.<br>
   if (Args.hasArg(options::OPT__SLASH_EP)) {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=228329&r1=228328&r2=228329&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=228329&r1=228328&r2=228329&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Thu Feb  5 12:56:03 2015<br>
@@ -3303,11 +3303,12 @@ StmtResult Sema::ActOnCXXTryBlock(Source<br>
   if (getCurScope() && getCurScope()->isOpenMPSimdDirectiveScope())<br>
     Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";<br>
<br>
+  sema::FunctionScopeInfo *FSI = getCurFunction();<br>
+<br>
   // C++ try is incompatible with SEH __try.<br>
-  if (!getLangOpts().Borland && getCurFunction()->FirstSEHTryLoc.isValid()) {<br>
+  if (!getLangOpts().Borland && FSI->FirstSEHTryLoc.isValid()) {<br>
     Diag(TryLoc, diag::err_mixing_cxx_try_seh_try);<br>
-    Diag(getCurFunction()->FirstSEHTryLoc, diag::note_conflicting_try_here)<br>
-        << "'__try'";<br>
+    Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'";<br>
   }<br>
<br>
   const unsigned NumHandlers = Handlers.size();<br>
@@ -3352,7 +3353,7 @@ StmtResult Sema::ActOnCXXTryBlock(Source<br>
     }<br>
   }<br>
<br>
-  getCurFunction()->setHasCXXTry(TryLoc);<br>
+  FSI->setHasCXXTry(TryLoc);<br>
<br>
   // FIXME: We should detect handlers that cannot catch anything because an<br>
   // earlier handler catches a superclass. Need to find a method that is not<br>
@@ -3367,15 +3368,29 @@ StmtResult Sema::ActOnSEHTryBlock(bool I<br>
                                   Stmt *TryBlock, Stmt *Handler) {<br>
   assert(TryBlock && Handler);<br>
<br>
+  sema::FunctionScopeInfo *FSI = getCurFunction();<br>
+<br>
   // SEH __try is incompatible with C++ try. Borland appears to support this,<br>
   // however.<br>
-  if (!getLangOpts().Borland && getCurFunction()->FirstCXXTryLoc.isValid()) {<br>
-    Diag(TryLoc, diag::err_mixing_cxx_try_seh_try);<br>
-    Diag(getCurFunction()->FirstCXXTryLoc, diag::note_conflicting_try_here)<br>
-        << "'try'";<br>
+  if (!getLangOpts().Borland) {<br>
+    if (FSI->FirstCXXTryLoc.isValid()) {<br>
+      Diag(TryLoc, diag::err_mixing_cxx_try_seh_try);<br>
+      Diag(FSI->FirstCXXTryLoc, diag::note_conflicting_try_here) << "'try'";<br>
+    }<br>
   }<br>
<br>
-  getCurFunction()->setHasSEHTry(TryLoc);<br>
+  FSI->setHasSEHTry(TryLoc);<br>
+<br>
+  // Reject __try in Obj-C methods, blocks, and captured decls, since we don't<br>
+  // track if they use SEH.<br>
+  DeclContext *DC = CurContext;<br>
+  while (DC && !DC->isFunctionOrMethod())<br>
+    DC = DC->getParent();<br>
+  FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(DC);<br>
+  if (FD)<br>
+    FD->setUsesSEHTry(true);<br>
+  else<br>
+    Diag(TryLoc, diag::err_seh_try_outside_functions);<br>
<br>
   return SEHTryStmt::Create(Context, IsCXXTry, TryLoc, TryBlock, Handler);<br>
 }<br>
<br>
Modified: cfe/trunk/test/CodeGen/exceptions-seh-finally.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-finally.c?rev=228329&r1=228328&r2=228329&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-finally.c?rev=228329&r1=228328&r2=228329&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/exceptions-seh-finally.c (original)<br>
+++ cfe/trunk/test/CodeGen/exceptions-seh-finally.c Thu Feb  5 12:56:03 2015<br>
@@ -1,4 +1,4 @@<br>
-// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fexceptions -fms-extensions -emit-llvm -o - | FileCheck %s<br>
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s<br>
<br>
 void abort(void) __attribute__((noreturn));<br>
 void might_crash(void);<br>
<br>
Modified: cfe/trunk/test/CodeGen/exceptions-seh-leave.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-leave.c?rev=228329&r1=228328&r2=228329&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh-leave.c?rev=228329&r1=228328&r2=228329&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/exceptions-seh-leave.c (original)<br>
+++ cfe/trunk/test/CodeGen/exceptions-seh-leave.c Thu Feb  5 12:56:03 2015<br>
@@ -1,4 +1,4 @@<br>
-// RUN: not %clang_cc1 -triple x86_64-pc-win32 -fexceptions -fms-extensions -emit-llvm -o - %s 2>&1 | FileCheck %s<br>
+// RUN: not %clang_cc1 -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - %s 2>&1 | FileCheck %s<br>
<br>
 // This is a codegen test because we only emit the diagnostic when we start<br>
 // generating code.<br>
<br>
Modified: cfe/trunk/test/CodeGen/exceptions-seh.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh.c?rev=228329&r1=228328&r2=228329&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/exceptions-seh.c?rev=228329&r1=228328&r2=228329&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGen/exceptions-seh.c (original)<br>
+++ cfe/trunk/test/CodeGen/exceptions-seh.c Thu Feb  5 12:56:03 2015<br>
@@ -1,4 +1,4 @@<br>
-// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fexceptions -fms-extensions -emit-llvm -o - | FileCheck %s<br>
+// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -fms-extensions -emit-llvm -o - | FileCheck %s<br>
<br>
 // FIXME: Perform this outlining automatically CodeGen.<br>
 void try_body(int numerator, int denominator, int *myres) {<br>
<br>
Added: cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp?rev=228329&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp?rev=228329&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp (added)<br>
+++ cfe/trunk/test/CodeGenCXX/exceptions-seh.cpp Thu Feb  5 12:56:03 2015<br>
@@ -0,0 +1,95 @@<br>
+// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \<br>
+// RUN:         -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | \<br>
+// RUN:         FileCheck %s --check-prefix=CHECK --check-prefix=CXXEH<br>
+// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \<br>
+// RUN:         -o - -mconstructor-aliases | \<br>
+// RUN:         FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX<br>
+<br>
+extern "C" void might_throw();<br>
+<br>
+struct HasCleanup {<br>
+  HasCleanup();<br>
+  ~HasCleanup();<br>
+  int padding;<br>
+};<br>
+<br>
+extern "C" void use_cxx() {<br>
+  HasCleanup x;<br>
+  might_throw();<br>
+}<br>
+<br>
+// Make sure we use __CxxFrameHandler3 for C++ EH.<br>
+<br>
+// CXXEH-LABEL: define void @use_cxx()<br>
+// CXXEH: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})<br>
+// CXXEH: invoke void @might_throw()<br>
+// CXXEH:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]<br>
+//<br>
+// CXXEH: [[cont]]<br>
+// CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})<br>
+// CXXEH: ret void<br>
+//<br>
+// CXXEH: [[lpad]]<br>
+// CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)<br>
+// CXXEH-NEXT: cleanup<br>
+// CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})<br>
+// CXXEH: br label %[[resume:[^ ]*]]<br>
+//<br>
+// CXXEH: [[resume]]<br>
+// CXXEH: resume<br>
+<br>
+// NOCXX-LABEL: define void @use_cxx()<br>
+// NOCXX-NOT: invoke<br>
+// NOCXX: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})<br>
+// NOCXX-NOT: invoke<br>
+// NOCXX: call void @might_throw()<br>
+// NOCXX-NOT: invoke<br>
+// NOCXX: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}})<br>
+// NOCXX-NOT: invoke<br>
+// NOCXX: ret void<br>
+<br>
+extern "C" void use_seh() {<br>
+  __try {<br>
+    might_throw();<br>
+  } __except(1) {<br>
+  }<br>
+}<br>
+<br>
+// Make sure we use __C_specific_handler for SEH.<br>
+<br>
+// CHECK-LABEL: define void @use_seh()<br>
+// CHECK: invoke void @might_throw()<br>
+// CHECK:       to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]]<br>
+//<br>
+// CHECK: [[cont]]<br>
+// CHECK: br label %[[ret:[^ ]*]]<br>
+//<br>
+// CHECK: [[lpad]]<br>
+// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)<br>
+// CHECK-NEXT: catch i8*<br>
+//<br>
+// CHECK: br label %[[ret]]<br>
+//<br>
+// CHECK: [[ret]]<br>
+// CHECK: ret void<br>
+<br>
+void use_seh_in_lambda() {<br>
+  ([]() {<br>
+    __try {<br>
+      might_throw();<br>
+    } __except(1) {<br>
+    }<br>
+  })();<br>
+  HasCleanup x;<br>
+  might_throw();<br>
+}<br>
+<br>
+// CXXEH-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"()<br>
+// CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*)<br>
+<br>
+// NOCXX-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"()<br>
+// NOCXX-NOT: invoke<br>
+// NOCXX: ret void<br>
+<br>
+// CHECK-LABEL: define internal void @"\01??R<lambda_0>@?use_seh_in_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this)<br>
+// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*)<br>
<br>
Modified: cfe/trunk/test/Driver/cl-eh.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/cl-eh.cpp?rev=228329&r1=228328&r2=228329&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/cl-eh.cpp?rev=228329&r1=228328&r2=228329&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Driver/cl-eh.cpp (original)<br>
+++ cfe/trunk/test/Driver/cl-eh.cpp Thu Feb  5 12:56:03 2015<br>
@@ -10,11 +10,11 @@<br>
<br>
 // RUN: %clang_cl /c /EHs-c- -### -- %s 2>&1 | FileCheck -check-prefix=EHs_c_ %s<br>
 // EHs_c_-NOT: "-fcxx-exceptions"<br>
-// EHs_c_: "-fexceptions"<br>
+// EHs_c_-NOT: "-fexceptions"<br>
<br>
 // RUN: %clang_cl /c /EHs- /EHc- -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHc_ %s<br>
 // EHs_EHc_-NOT: "-fcxx-exceptions"<br>
-// EHs_EHc_: "-fexceptions"<br>
+// EHs_EHc_-NOT: "-fexceptions"<br>
<br>
 // RUN: %clang_cl /c /EHs- /EHs -### -- %s 2>&1 | FileCheck -check-prefix=EHs_EHs %s<br>
 // EHs_EHs: "-fcxx-exceptions"<br>
<br>
Modified: cfe/trunk/test/SemaCXX/exceptions-seh.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/exceptions-seh.cpp?rev=228329&r1=228328&r2=228329&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/exceptions-seh.cpp?rev=228329&r1=228328&r2=228329&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/exceptions-seh.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/exceptions-seh.cpp Thu Feb  5 12:56:03 2015<br>
@@ -1,4 +1,5 @@<br>
-// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s<br>
+// RUN: %clang_cc1 -std=c++03 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s<br>
+// RUN: %clang_cc1 -std=c++11 -fblocks -triple x86_64-windows-msvc -fms-extensions -fsyntax-only -fexceptions -fcxx-exceptions -verify %s<br>
<br>
 // Basic usage should work.<br>
 int safe_div(int n, int d) {<br>
@@ -37,6 +38,7 @@ void instantiate_bad_scope_tmpl() {<br>
   bad_builtin_scope_template<might_crash>();<br>
 }<br>
<br>
+#if __cplusplus < 201103L<br>
 // FIXME: Diagnose this case. For now we produce undef in codegen.<br>
 template <typename T, T FN()><br>
 T func_template() {<br>
@@ -46,6 +48,7 @@ void inject_builtins() {<br>
   func_template<void *, __exception_info>();<br>
   func_template<unsigned long, __exception_code>();<br>
 }<br>
+#endif<br>
<br>
 void use_seh_after_cxx() {<br>
   try { // expected-note {{conflicting 'try' here}}<br>
@@ -68,3 +71,45 @@ void use_cxx_after_seh() {<br>
   } catch (int) {<br>
   }<br>
 }<br>
+<br>
+#if __cplusplus >= 201103L<br>
+void use_seh_in_lambda() {<br>
+  ([]() {<br>
+    __try {<br>
+      might_crash();<br>
+    } __except(1) {<br>
+    }<br>
+  })();<br>
+  try {<br>
+    might_crash();<br>
+  } catch (int) {<br>
+  }<br>
+}<br>
+#endif<br>
+<br>
+void use_seh_in_block() {<br>
+  void (^b)() = ^{<br>
+    __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}}<br>
+      might_crash();<br>
+    } __except(1) {<br>
+    }<br>
+  };<br>
+  try {<br>
+    b();<br>
+  } catch (int) {<br>
+  }<br>
+}<br>
+<br>
+void (^use_seh_in_global_block)() = ^{<br>
+  __try { // expected-error {{cannot use SEH '__try' in blocks, captured regions, or Obj-C method decls}}<br>
+    might_crash();<br>
+  } __except(1) {<br>
+  }<br>
+};<br>
+<br>
+void (^use_cxx_in_global_block)() = ^{<br>
+  try {<br>
+    might_crash();<br>
+  } catch(int) {<br>
+  }<br>
+};<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div>
______________________________<u></u>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/cfe-commits</a><br>
</blockquote></div>