The -EHc flag implicitly adds a nothrow attribute to any extern "C"
function when exceptions are enabled.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@261425
91177308-0d34-0410-b5e6-
96231b3b80d8
LANGOPT(ObjCExceptions , 1, 0, "Objective-C exceptions")
LANGOPT(CXXExceptions , 1, 0, "C++ exceptions")
LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump 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")
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")
def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">,
HelpText<"Weakly link in the blocks runtime">;
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">,
def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">,
HelpText<"Use SjLj style exceptions">;
def split_dwarf_file : Separate<["-"], "split-dwarf-file">,
/// - 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.
/// - 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;
/// The default is /EHs-c-, meaning cleanups are disabled.
static EHFlags parseClangCLEHFlags(const Driver &D, const ArgList &Args) {
EHFlags EH;
const Driver &D = getToolChain().getDriver();
EHFlags EH = parseClangCLEHFlags(D, Args);
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.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.
}
// /EP should expand to -E -P.
Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions);
Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
Opts.SjLjExceptions = Args.hasArg(OPT_fsjlj_exceptions);
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);
Opts.TraditionalCPP = Args.hasArg(OPT_traditional_cpp);
Opts.RTTI = Opts.CPlusPlus && !Args.hasArg(OPT_fno_rtti);
+ // 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;
IdentifierInfo *Name = FD->getIdentifier();
if (!Name)
return;