diff options
-rw-r--r-- | clang/include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Frontend/CodeGenOptions.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDeclCXX.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 5 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 3 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/apple-kext-guard-variable.cpp | 9 |
8 files changed, 39 insertions, 0 deletions
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index c0fb23deb07..e103b5bb7d8 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -110,6 +110,8 @@ def disable_red_zone : Flag<"-disable-red-zone">, HelpText<"Do not emit code that uses the red zone.">; def dwarf_debug_flags : Separate<"-dwarf-debug-flags">, HelpText<"The string to embed in the Dwarf debug flags record.">; +def fforbid_guard_variables : Flag<"-fforbid-guard-variables">, + HelpText<"Emit an error if a C++ static local initializer would need a guard variable">; def g : Flag<"-g">, HelpText<"Generate source level debug information">; def fcatch_undefined_behavior : Flag<"-fcatch-undefined-behavior">, HelpText<"Generate runtime checks for undefined behavior.">; diff --git a/clang/include/clang/Frontend/CodeGenOptions.h b/clang/include/clang/Frontend/CodeGenOptions.h index ee85b655c23..875fbcd1772 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.h +++ b/clang/include/clang/Frontend/CodeGenOptions.h @@ -51,6 +51,8 @@ public: /// Decl* various IR entities came from. Only /// useful when running CodeGen as a /// subroutine. + unsigned ForbidGuardVariables : 1; /// Issue errors if C++ guard variables + /// are required unsigned FunctionSections : 1; /// Set when -ffunction-sections is enabled unsigned HiddenWeakTemplateVTables : 1; /// Emit weak vtables and RTTI for /// template classes with hidden visibility @@ -128,6 +130,7 @@ public: DisableLLVMOpts = 0; DisableRedZone = 0; EmitDeclMetadata = 0; + ForbidGuardVariables = 0; FunctionSections = 0; HiddenWeakTemplateVTables = 0; HiddenWeakVTables = 0; diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 6635af88939..ed25b6db38e 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -149,6 +149,14 @@ CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn, void CodeGenFunction::EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr) { + // If we've been asked to forbid guard variables, emit an error now. + // This diagnostic is hard-coded for Darwin's use case; we can find + // better phrasing if someone else needs it. + if (CGM.getCodeGenOpts().ForbidGuardVariables) + CGM.Error(D.getLocation(), + "this initialization requires a guard variable, which " + "the kernel does not support"); + CGM.getCXXABI().EmitGuardedInit(*this, D, DeclPtr); } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 61814702bdd..11e85870d14 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -154,6 +154,11 @@ bool CodeGenModule::isTargetDarwin() const { return getContext().Target.getTriple().getOS() == llvm::Triple::Darwin; } +void CodeGenModule::Error(SourceLocation loc, llvm::StringRef error) { + unsigned diagID = getDiags().getCustomDiagID(Diagnostic::Error, error); + getDiags().Report(Context.getFullLoc(loc), diagID); +} + /// ErrorUnsupported - Print out an error that codegen doesn't support the /// specified stmt yet. void CodeGenModule::ErrorUnsupported(const Stmt *S, const char *Type, diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 02057970b64..5b8164f6be3 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -527,6 +527,9 @@ public: llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV, const AnnotateAttr *AA, unsigned LineNo); + /// Error - Emit a general error that something can't be done. + void Error(SourceLocation loc, llvm::StringRef error); + /// ErrorUnsupported - Print out an error that codegen doesn't support the /// specified stmt yet. /// \param OmitOnError - If true, then this error should only be emitted if no diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 45fdd8be2e6..ee4976ee72b 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1138,6 +1138,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().getTriple().getOS() != llvm::Triple::Darwin) CmdArgs.push_back("-mconstructor-aliases"); + // Darwin's kernel doesn't support guard variables; just die if we + // try to use them. + if (KernelOrKext && + getToolChain().getTriple().getOS() == llvm::Triple::Darwin) + CmdArgs.push_back("-fforbid-guard-variables"); + if (Args.hasArg(options::OPT_mms_bitfields)) { CmdArgs.push_back("-mms-bitfields"); } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 859eb74a8a0..31fcee2de88 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -127,6 +127,8 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts, Res.push_back("-fno-merge-all-constants"); if (Opts.NoCommon) Res.push_back("-fno-common"); + if (Opts.ForbidGuardVariables) + Res.push_back("-fforbid-guard-variables"); if (Opts.NoImplicitFloat) Res.push_back("-no-implicit-float"); if (Opts.OmitLeafFramePointer) @@ -896,6 +898,7 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.LimitDebugInfo = Args.hasArg(OPT_flimit_debug_info); Opts.DisableLLVMOpts = Args.hasArg(OPT_disable_llvm_optzns); Opts.DisableRedZone = Args.hasArg(OPT_disable_red_zone); + Opts.ForbidGuardVariables = Args.hasArg(OPT_fforbid_guard_variables); Opts.RelaxedAliasing = Args.hasArg(OPT_relaxed_aliasing); Opts.DwarfDebugFlags = Args.getLastArgValue(OPT_dwarf_debug_flags); Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants); diff --git a/clang/test/CodeGenCXX/apple-kext-guard-variable.cpp b/clang/test/CodeGenCXX/apple-kext-guard-variable.cpp new file mode 100644 index 00000000000..f9d44603a84 --- /dev/null +++ b/clang/test/CodeGenCXX/apple-kext-guard-variable.cpp @@ -0,0 +1,9 @@ +// RUN: %clang -mtriple=x86_64-apple-darwin10 -S -mkernel -Xclang -verify %s + +// rdar://problem/9143356 + +int foo(); +void test() { + static int y = 0; + static int x = foo(); // expected-error {{this initialization requires a guard variable, which the kernel does not support}} +} |