]> granicus.if.org Git - clang/commitdiff
[clang-cl] /EHc should not effect functions with explicit exception specifications
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 29 Feb 2016 01:40:36 +0000 (01:40 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 29 Feb 2016 01:40:36 +0000 (01:40 +0000)
Functions with an explicit exception specification have their behavior
dictated by the specification.  The additional /EHc behavior only comes
into play if no exception specification is given.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@262198 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Driver/Tools.cpp
lib/Driver/Tools.h
lib/Sema/SemaDecl.cpp
test/CodeGenCXX/exceptions-cxx-ehsc.cpp
test/Driver/cl-options.c

index 2841dab169ebcd14e988703219cc5c192f3eacf4..e5dbe9bae0cd8a15a9060e75d871c3e07db9c3d5 100644 (file)
@@ -4119,8 +4119,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
   bool EmitCodeView = false;
 
   // Add clang-cl arguments.
+  types::ID InputType = Input.getType();
   if (getToolChain().getDriver().IsCLMode())
-    AddClangCLArgs(Args, CmdArgs, &DebugInfoKind, &EmitCodeView);
+    AddClangCLArgs(Args, InputType, CmdArgs, &DebugInfoKind, &EmitCodeView);
 
   // Pass the linker version in use.
   if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) {
@@ -4133,7 +4134,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
 
   // Explicitly error on some things we know we don't support and can't just
   // ignore.
-  types::ID InputType = Input.getType();
   if (!Args.hasArg(options::OPT_fallow_unsupported)) {
     Arg *Unsupported;
     if (types::isCXX(InputType) && getToolChain().getTriple().isOSDarwin() &&
@@ -5859,7 +5859,8 @@ static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
   return EH;
 }
 
-void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs,
+void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
+                           ArgStringList &CmdArgs,
                            codegenoptions::DebugInfoKind *DebugInfoKind,
                            bool *EmitCodeView) const {
   unsigned RTOptionID = options::OPT__SLASH_MT;
@@ -5934,11 +5935,12 @@ void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs,
   const Driver &D = getToolChain().getDriver();
   EHFlags EH = parseClangCLEHFlags(D, Args);
   if (EH.Synch || EH.Asynch) {
-    CmdArgs.push_back("-fcxx-exceptions");
+    if (types::isCXX(InputType))
+      CmdArgs.push_back("-fcxx-exceptions");
     CmdArgs.push_back("-fexceptions");
-    if (EH.Synch && EH.NoUnwindC)
-      CmdArgs.push_back("-fexternc-nounwind");
   }
+  if (types::isCXX(InputType) && EH.Synch && EH.NoUnwindC)
+    CmdArgs.push_back("-fexternc-nounwind");
 
   // /EP should expand to -E -P.
   if (Args.hasArg(options::OPT__SLASH_EP)) {
index 1d348bbbd689918af3cbc5b4638b98d6875e4c0b..6884cd42f3b385f948ae47fc0b3b2b4eeae44464 100644 (file)
@@ -91,7 +91,7 @@ private:
                                  llvm::opt::ArgStringList &cmdArgs,
                                  RewriteKind rewrite) const;
 
-  void AddClangCLArgs(const llvm::opt::ArgList &Args,
+  void AddClangCLArgs(const llvm::opt::ArgList &Args, types::ID InputType,
                       llvm::opt::ArgStringList &CmdArgs,
                       codegenoptions::DebugInfoKind *DebugInfoKind,
                       bool *EmitCodeView) const;
index 4a1bbde271d2d166a5c75beebdd32420f99498ce..f7fe506f4ae2227fcc4da6c974421e57a8abd6b0 100644 (file)
@@ -11635,8 +11635,11 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
   // throw, add an implicit nothrow attribute to any extern "C" function we come
   // across.
   if (getLangOpts().CXXExceptions && getLangOpts().ExternCNoUnwind &&
-      FD->isExternC() && !FD->hasAttr<NoThrowAttr>())
-    FD->addAttr(NoThrowAttr::CreateImplicit(Context, FD->getLocation()));
+      FD->isExternC() && !FD->hasAttr<NoThrowAttr>()) {
+    const auto *FPT = FD->getType()->getAs<FunctionProtoType>();
+    if (!FPT || FPT->getExceptionSpecType() == EST_None)
+      FD->addAttr(NoThrowAttr::CreateImplicit(Context, FD->getLocation()));
+  }
 
   IdentifierInfo *Name = FD->getIdentifier();
   if (!Name)
index 423c1b74cc2e808d6bd54cb9baac777c32ab8ab7..c660d145393a16ddbb58efca3dbd4168b295bcb5 100644 (file)
@@ -14,3 +14,18 @@ void caller() {
 // CHECK-LABEL: define void @"\01?caller@test1@@YAXXZ"(
 // CHECK: call void @never_throws(
 // CHECK: invoke void @"\01?may_throw@test1@@YAXXZ"(
+
+namespace test2 {
+struct Cleanup { ~Cleanup(); };
+extern "C" void throws_int() throw(int);
+void may_throw();
+
+void caller() {
+  Cleanup x;
+  throws_int();
+  may_throw();
+}
+}
+// CHECK-LABEL: define void @"\01?caller@test2@@YAXXZ"(
+// CHECK: invoke void @throws_int(
+// CHECK: invoke void @"\01?may_throw@test2@@YAXXZ"(
index 8a3cb4473e6932cde8af3ff888938e8372ced6a3..e637d7ac4c33a352101ec18485e6689e82027296 100644 (file)
 // RUN: %clang_cl /FI asdf.h -### -- %s 2>&1 | FileCheck -check-prefix=FI_ %s
 // FI_: "-include" "asdf.h"
 
-// RUN: %clang_cl /c -### -- %s 2>&1 | FileCheck -check-prefix=NO-GX %s
+// RUN: %clang_cl /TP /c -### -- %s 2>&1 | FileCheck -check-prefix=NO-GX %s
 // NO-GX-NOT: "-fcxx-exceptions" "-fexceptions"
 
-// RUN: %clang_cl /c /GX -### -- %s 2>&1 | FileCheck -check-prefix=GX %s
+// RUN: %clang_cl /TP /c /GX -### -- %s 2>&1 | FileCheck -check-prefix=GX %s
 // GX: "-fcxx-exceptions" "-fexceptions"
 
-// RUN: %clang_cl /c /GX /GX- -### -- %s 2>&1 | FileCheck -check-prefix=GX_ %s
+// RUN: %clang_cl /TP /c /GX /GX- -### -- %s 2>&1 | FileCheck -check-prefix=GX_ %s
 // GX_-NOT: "-fcxx-exceptions" "-fexceptions"
 
 // We forward any unrecognized -W diagnostic options to cc1.