diff options
author | David Majnemer <david.majnemer@gmail.com> | 2016-02-20 09:23:47 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2016-02-20 09:23:47 +0000 |
commit | 960813e1643ec788707bf18b0cdce4bb142d560a (patch) | |
tree | 2b288c4a0e9e8686841868ba4d58f22ec95a3dbe | |
parent | b880909ab5b98baa7d69cf84a8b5c82586c60df5 (diff) | |
download | bcm5719-llvm-960813e1643ec788707bf18b0cdce4bb142d560a.tar.gz bcm5719-llvm-960813e1643ec788707bf18b0cdce4bb142d560a.zip |
[MSVC Compat] Implement -EHc semantics
The -EHc flag implicitly adds a nothrow attribute to any extern "C"
function when exceptions are enabled.
llvm-svn: 261425
-rw-r--r-- | clang/include/clang/Basic/LangOptions.def | 1 | ||||
-rw-r--r-- | clang/include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 7 |
5 files changed, 14 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index a3ee84291fd..623e896bbd9 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -110,6 +110,7 @@ LANGOPT(Exceptions , 1, 0, "exception handling") LANGOPT(ObjCExceptions , 1, 0, "Objective-C exceptions") LANGOPT(CXXExceptions , 1, 0, "C++ exceptions") LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling") +LANGOPT(ExternCNoUnwind , 1, 0, "Assume extern C functions don't unwind") LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation") LANGOPT(RTTI , 1, 1, "run-time type information") LANGOPT(RTTIData , 1, 1, "emit run-time type information data") diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index 721c30f1b13..b725b5f6af9 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -511,6 +511,8 @@ def main_file_name : Separate<["-"], "main-file-name">, def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">, HelpText<"Weakly link in the blocks runtime">; +def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">, + HelpText<"Assume all functions with C linkage do not unwind">; def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">, HelpText<"Use SjLj style exceptions">; def split_dwarf_file : Separate<["-"], "split-dwarf-file">, 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; |