]> granicus.if.org Git - clang/commitdiff
The Darwin kernel does not provide useful guard variable support.
authorJohn McCall <rjmccall@apple.com>
Fri, 18 Mar 2011 02:56:14 +0000 (02:56 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 18 Mar 2011 02:56:14 +0000 (02:56 +0000)
Issue this as an IR-gen error;  it's not really worthwhile doing this
"right", i.e. in Sema, because IR gen knows a lot of tricks beyond
what the constant evaluator knows.

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

include/clang/Driver/CC1Options.td
include/clang/Frontend/CodeGenOptions.h
lib/CodeGen/CGDeclCXX.cpp
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
test/CodeGenCXX/apple-kext-guard-variable.cpp [new file with mode: 0644]

index c0fb23deb0782a210c4969e2331a0e2fd981408f..e103b5bb7d8287e87a0f94aa382cfdfd186521ce 100644 (file)
@@ -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.">;
index ee85b655c23f5ad9433da6b26f7b397010ead993..875fbcd177222981cdf8d95c8f57a759742e3a1d 100644 (file)
@@ -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;
index 6635af88939f5b1f9e98e819d768baf7de6fc0a0..ed25b6db38e5ce83aff534f1a906ed27c6c872e4 100644 (file)
@@ -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);
 }
 
index 61814702bdd650712fe52abcba58e058949f2b3d..11e85870d14a6de9b38147ef83ec312093042b84 100644 (file)
@@ -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,
index 02057970b644061075751b2bab32507d6c94967b..5b8164f6be366a7823aaa618918fed7e3ea3d9d6 100644 (file)
@@ -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
index 45fdd8be2e62e6772b555276f3142ae6a1efeaa2..ee4976ee72b482716602fc8519b3b9901e2230bc 100644 (file)
@@ -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");
   }
index 859eb74a8a0cc19f08044c9a99413503b3356489..31fcee2de888a48990b661b7630518f26a918383 100644 (file)
@@ -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/test/CodeGenCXX/apple-kext-guard-variable.cpp b/test/CodeGenCXX/apple-kext-guard-variable.cpp
new file mode 100644 (file)
index 0000000..f9d4460
--- /dev/null
@@ -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}}
+}