summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Driver/Tools.cpp6
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp1
-rw-r--r--clang/lib/Sema/SemaDecl.cpp7
3 files changed, 11 insertions, 3 deletions
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 9c64da58c27..fd647a484e6 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -5786,8 +5786,7 @@ struct EHFlags {
/// - s: Cleanup after "synchronous" exceptions, aka C++ exceptions.
/// - a: Cleanup after "asynchronous" exceptions, aka structured exceptions.
/// The 'a' modifier is unimplemented and fundamentally hard in LLVM IR.
-/// - c: Assume that extern "C" functions are implicitly noexcept. This
-/// modifier is an optimization, so we ignore it for now.
+/// - c: Assume that extern "C" functions are implicitly nounwind.
/// The default is /EHs-c-, meaning cleanups are disabled.
static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
EHFlags EH;
@@ -5897,10 +5896,11 @@ void Clang::AddClangCLArgs(const ArgList &Args, ArgStringList &CmdArgs,
const Driver &D = getToolChain().getDriver();
EHFlags EH = parseClangCLEHFlags(D, Args);
- // FIXME: Do something with NoExceptC.
if (EH.Synch || EH.Asynch) {
CmdArgs.push_back("-fcxx-exceptions");
CmdArgs.push_back("-fexceptions");
+ if (EH.NoUnwindC)
+ CmdArgs.push_back("-fexternc-nounwind");
}
// /EP should expand to -E -P.
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2e0822794ee..cf4b5cf20a1 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1688,6 +1688,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions);
Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
Opts.SjLjExceptions = Args.hasArg(OPT_fsjlj_exceptions);
+ Opts.ExternCNoUnwind = Args.hasArg(OPT_fexternc_nounwind);
Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp);
Opts.RTTI = Opts.CPlusPlus && !Args.hasArg(OPT_fno_rtti);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 62cd5c8e3db..a775be9ea25 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11582,6 +11582,13 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
}
}
+ // If C++ exceptions are enabled but we are told extern "C" functions cannot
+ // 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()));
+
IdentifierInfo *Name = FD->getIdentifier();
if (!Name)
return;
OpenPOWER on IntegriCloud