[cfe-commits] r168297 - in /cfe/trunk: include/clang/Basic/DiagnosticDriverKinds.td include/clang/Driver/ToolChain.h lib/Driver/ToolChains.cpp lib/Driver/ToolChains.h lib/Driver/Tools.cpp lib/Driver/WindowsToolChain.cpp test/Driver/pic.c

Chandler Carruth chandlerc at gmail.com
Sun Nov 18 19:52:03 PST 2012


Author: chandlerc
Date: Sun Nov 18 21:52:03 2012
New Revision: 168297

URL: http://llvm.org/viewvc/llvm-project?rev=168297&view=rev
Log:
Completely re-work how the Clang driver interprets PIC and PIE options.

There were numerous issues here that were all entangled, and so I've
tried to do a general simplification of the logic.
1) The logic was mimicing actual GCC bugs, rather than "features". These
   have been fixed in trunk GCC, and this fixes Clang as well. Notably,
   the logic was always intended to be last-match-wins like any other
   flag.
2) The logic for handling '-mdynamic-no-pic' was preposterously unclear.
   It also allowed the use of this flag on non-Darwin platforms where it
   has no actual meaning. Now this option is handled directly based on
   tests of how llvm-gcc behaves, and it is only supported on Darwin.
3) The APIs for the Driver's ToolChains had the implementation ugliness
   of dynamic-no-pic leaking through them. They also had the
   implementation details of the LLVM relocation model flag names
   leaking through.
4) The actual results of passing these flags was incorrect on Darwin in
   many cases. For example, Darwin *always* uses PIC level 2 if it uses
   in PIC level, and Darwin *always* uses PIC on 64-bit regardless of
   the flags specified, including -fPIE. Darwin never compiles in PIE
   mode, but it can *link* in PIE mode.
5) Also, PIC was not always being enabled even when PIE was. This isn't
   a supported mode at all and may have caused some fallout in builds
   with complex PIC and PIE interactions.

The result is (I hope) cleaner and clearer for readers. I've also left
comments and tests about some of the truly strage behavior that is
observed on Darwin platforms. We have no real testing of Windows
platforms and PIC, but I don't have the tools handy to figure that out.
Hopefully others can beef up our testing here.

Unfortunately, I can't test this for every platform. =/ If folks have
dependencies on these flags that aren't covered by tests, they may
break. I've audited and ensured that all the changes in behavior of the
existing tests are intentional and good. In particular I've tried to
make sure the Darwin behavior (which is more suprising than the Linux
behavior) also matches that of 'gcc' on my mac.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
    cfe/trunk/include/clang/Driver/ToolChain.h
    cfe/trunk/lib/Driver/ToolChains.cpp
    cfe/trunk/lib/Driver/ToolChains.h
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/lib/Driver/WindowsToolChain.cpp
    cfe/trunk/test/Driver/pic.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td?rev=168297&r1=168296&r2=168297&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td Sun Nov 18 21:52:03 2012
@@ -11,6 +11,8 @@
 
 def err_drv_no_such_file : Error<"no such file or directory: '%0'">;
 def err_drv_unsupported_opt : Error<"unsupported option '%0'">;
+def err_drv_unsupported_opt_for_target : Error<
+  "unsupported option '%0' for target '%1'">;
 def err_drv_unsupported_option_argument : Error<
   "unsupported argument '%1' to option '%0'">;
 def err_drv_unknown_stdin_type : Error<

Modified: cfe/trunk/include/clang/Driver/ToolChain.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=168297&r1=168296&r2=168297&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/ToolChain.h (original)
+++ cfe/trunk/include/clang/Driver/ToolChain.h Sun Nov 18 21:52:03 2012
@@ -176,14 +176,13 @@
   /// by default.
   virtual bool IsUnwindTablesDefault() const;
 
-  /// GetDefaultRelocationModel - Return the LLVM name of the default
-  /// relocation model for this tool chain.
-  virtual const char *GetDefaultRelocationModel() const = 0;
-
-  /// GetForcedPicModel - Return the LLVM name of the forced PIC model
-  /// for this tool chain, or 0 if this tool chain does not force a
-  /// particular PIC mode.
-  virtual const char *GetForcedPicModel() const = 0;
+  /// \brief Test whether this toolchain defaults to PIC.
+  virtual bool isPICDefault() const = 0;
+
+  /// \brief Tests whether this toolchain forces its default for PIC or non-PIC.
+  /// If this returns true, any PIC related flags should be ignored and instead
+  /// the result of \c isPICDefault() is used exclusively.
+  virtual bool isPICDefaultForced() const = 0;
 
   /// SupportsProfiling - Does this tool chain support -pg.
   virtual bool SupportsProfiling() const { return true; }

Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=168297&r1=168296&r2=168297&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Sun Nov 18 21:52:03 2012
@@ -886,14 +886,12 @@
           getTriple().getArch() == llvm::Triple::thumb);
 }
 
-const char *Darwin::GetDefaultRelocationModel() const {
-  return "pic";
+bool Darwin::isPICDefault() const {
+  return true;
 }
 
-const char *Darwin::GetForcedPicModel() const {
-  if (getArch() == llvm::Triple::x86_64)
-    return "pic";
-  return 0;
+bool Darwin::isPICDefaultForced() const {
+  return getArch() == llvm::Triple::x86_64;
 }
 
 bool Darwin::SupportsProfiling() const {
@@ -1395,13 +1393,14 @@
   return getArch() == llvm::Triple::x86_64;
 }
 
-const char *Generic_GCC::GetDefaultRelocationModel() const {
-  return "static";
+bool Generic_GCC::isPICDefault() const {
+  return false;
 }
 
-const char *Generic_GCC::GetForcedPicModel() const {
-  return 0;
+bool Generic_GCC::isPICDefaultForced() const {
+  return false;
 }
+
 /// Hexagon Toolchain
 
 Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple& Triple)
@@ -1455,14 +1454,13 @@
   return *T;
 }
 
-const char *Hexagon_TC::GetDefaultRelocationModel() const {
-  return "static";
+bool Hexagon_TC::isPICDefault() const {
+  return false;
 }
 
-const char *Hexagon_TC::GetForcedPicModel() const {
-  return 0;
-} // End Hexagon
-
+bool Hexagon_TC::isPICDefaultForced() const {
+  return false;
+}
 
 /// TCEToolChain - A tool chain using the llvm bitcode tools to perform
 /// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
@@ -1487,12 +1485,12 @@
   return true;
 }
 
-const char *TCEToolChain::GetDefaultRelocationModel() const {
-  return "static";
+bool TCEToolChain::isPICDefault() const {
+  return false;
 }
 
-const char *TCEToolChain::GetForcedPicModel() const {
-  return 0;
+bool TCEToolChain::isPICDefaultForced() const {
+  return false;
 }
 
 Tool &TCEToolChain::SelectTool(const Compilation &C,

Modified: cfe/trunk/lib/Driver/ToolChains.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.h?rev=168297&r1=168296&r2=168297&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.h (original)
+++ cfe/trunk/lib/Driver/ToolChains.h Sun Nov 18 21:52:03 2012
@@ -129,8 +129,8 @@
                            const ActionList &Inputs) const;
 
   virtual bool IsUnwindTablesDefault() const;
-  virtual const char *GetDefaultRelocationModel() const;
-  virtual const char *GetForcedPicModel() const;
+  virtual bool isPICDefault() const;
+  virtual bool isPICDefaultForced() const;
 
 protected:
   /// \name ToolChain Implementation Helper Functions
@@ -156,8 +156,8 @@
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
 
-  virtual const char *GetDefaultRelocationModel() const;
-  virtual const char *GetForcedPicModel() const;
+  virtual bool isPICDefault() const;
+  virtual bool isPICDefaultForced() const;
 };
 
   /// Darwin - The base Darwin tool chain.
@@ -344,8 +344,8 @@
   virtual RuntimeLibType GetDefaultRuntimeLibType() const {
     return ToolChain::RLT_CompilerRT;
   }
-  virtual const char *GetDefaultRelocationModel() const;
-  virtual const char *GetForcedPicModel() const;
+  virtual bool isPICDefault() const;
+  virtual bool isPICDefaultForced() const;
 
   virtual bool SupportsProfiling() const;
 
@@ -393,7 +393,7 @@
   std::string ComputeEffectiveClangTriple(const ArgList &Args,
                                           types::ID InputType) const;
 
-  virtual const char *GetDefaultRelocationModel() const { return "pic"; }
+  virtual bool isPICDefault() const { return false; };
 };
 
 class LLVM_LIBRARY_VISIBILITY Generic_ELF : public Generic_GCC {
@@ -534,8 +534,8 @@
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
   bool IsMathErrnoDefault() const;
-  const char* GetDefaultRelocationModel() const;
-  const char* GetForcedPicModel() const;
+  bool isPICDefault() const;
+  bool isPICDefaultForced() const;
 
 private:
   mutable llvm::DenseMap<unsigned, Tool*> Tools;
@@ -557,8 +557,8 @@
 
   virtual bool IsIntegratedAssemblerDefault() const;
   virtual bool IsUnwindTablesDefault() const;
-  virtual const char *GetDefaultRelocationModel() const;
-  virtual const char *GetForcedPicModel() const;
+  virtual bool isPICDefault() const;
+  virtual bool isPICDefaultForced() const;
 
   virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
                                          ArgStringList &CC1Args) const;

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=168297&r1=168296&r2=168297&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Sun Nov 18 21:52:03 2012
@@ -1769,38 +1769,46 @@
 
   CheckCodeGenerationOptions(D, Args);
 
-  // Perform argument translation for LLVM backend. This
-  // takes some care in reconciling with llvm-gcc. The
-  // issue is that llvm-gcc translates these options based on
-  // the values in cc1, whereas we are processing based on
-  // the driver arguments.
-
-  // This comes from the default translation the driver + cc1
-  // would do to enable flag_pic.
-
-  Arg *LastPICArg = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
-                                    options::OPT_fpic, options::OPT_fno_pic);
-  // We need to check for PIE flags separately because they can override the
-  // PIC flags.
-  Arg *LastPIEArg = Args.getLastArg(options::OPT_fPIE, options::OPT_fno_PIE,
-                                    options::OPT_fpie, options::OPT_fno_pie);
-  bool PICDisabled = false;
-  bool PICEnabled = false;
-  bool PICForPIE = false;
-  if (LastPIEArg) {
-    PICForPIE = (LastPIEArg->getOption().matches(options::OPT_fPIE) ||
-                 LastPIEArg->getOption().matches(options::OPT_fpie));
-  }
-  if (LastPICArg || PICForPIE) {
-    // The last PIE enabled argument can infer that PIC is enabled.
-    PICEnabled = (PICForPIE ||
-                  LastPICArg->getOption().matches(options::OPT_fPIC) ||
-                  LastPICArg->getOption().matches(options::OPT_fpic));
-    // We need to have PICDisabled inside the if statement because on darwin
-    // PIC is enabled by default even if PIC arguments are not in the command
-    // line (in this case causes PICDisabled to be true).
-    PICDisabled = !PICEnabled;
+  // For the PIC and PIE flag options, this logic is different from the legacy
+  // logic in very old versions of GCC, as that logic was just a bug no one had
+  // ever fixed. This logic is both more rational and consistent with GCC's new
+  // logic now that the bugs are fixed. The last argument relating to either
+  // PIC or PIE wins, and no other argument is used. If the last argument is
+  // any flavor of the '-fno-...' arguments, both PIC and PIE are disabled. Any
+  // PIE option implicitly enables PIC at the same level.
+  bool PIE = false;
+  bool PIC = getToolChain().isPICDefault();
+  bool IsPICLevelTwo = PIC;
+  if (Arg *A = Args.getLastArg(options::OPT_fPIC, options::OPT_fno_PIC,
+                               options::OPT_fpic, options::OPT_fno_pic,
+                               options::OPT_fPIE, options::OPT_fno_PIE,
+                               options::OPT_fpie, options::OPT_fno_pie)) {
+    Option O = A->getOption();
+    if (O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic) ||
+        O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie)) {
+      PIE = O.matches(options::OPT_fPIE) || O.matches(options::OPT_fpie);
+      PIC = PIE || O.matches(options::OPT_fPIC) || O.matches(options::OPT_fpic);
+      IsPICLevelTwo = O.matches(options::OPT_fPIE) ||
+                      O.matches(options::OPT_fPIC);
+    } else {
+      PIE = PIC = false;
+    }
   }
+  // Check whether the tool chain trumps the PIC-ness decision. If the PIC-ness
+  // is forced, then neither PIC nor PIE flags will have no effect.
+  if (getToolChain().isPICDefaultForced()) {
+    PIE = false;
+    PIC = getToolChain().isPICDefault();
+    IsPICLevelTwo = PIC;
+  }
+
+  // Inroduce a Darwin-specific hack. If the default is PIC but the flags
+  // specified while enabling PIC enabled level 1 PIC, just force it back to
+  // level 2 PIC instead. This matches the behavior of Darwin GCC (based on my
+  // informal testing).
+  if (PIC && getToolChain().getTriple().isOSDarwin())
+    IsPICLevelTwo |= getToolChain().isPICDefault();
+
   // Note that these flags are trump-cards. Regardless of the order w.r.t. the
   // PIC or PIE options above, if these show up, PIC is disabled.
   llvm::Triple Triple(TripleStr);
@@ -1808,44 +1816,43 @@
        Args.hasArg(options::OPT_fapple_kext)) &&
       (Triple.getOS() != llvm::Triple::IOS ||
        Triple.isOSVersionLT(6)))
-    PICDisabled = true;
+    PIC = PIE = false;
   if (Args.hasArg(options::OPT_static))
-    PICDisabled = true;
-  bool DynamicNoPIC = Args.hasArg(options::OPT_mdynamic_no_pic);
+    PIC = PIE = false;
+
+  if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) {
+    // This is a very special mode. It trumps the other modes, almost no one
+    // uses it, and it isn't even valid on any OS but Darwin.
+    if (!getToolChain().getTriple().isOSDarwin())
+      D.Diag(diag::err_drv_unsupported_opt_for_target)
+        << A->getSpelling() << getToolChain().getTriple().str();
+
+    // FIXME: Warn when this flag trumps some other PIC or PIE flag.
 
-  // Select the relocation model.
-  const char *Model = getToolChain().GetForcedPicModel();
-  if (!Model) {
-    if (DynamicNoPIC)
-      Model = "dynamic-no-pic";
-    else if (PICDisabled)
-      Model = "static";
-    else if (PICEnabled)
-      Model = "pic";
-    else
-      Model = getToolChain().GetDefaultRelocationModel();
-  }
-  StringRef ModelStr = Model ? Model : "";
-  if (Model && ModelStr != "pic") {
     CmdArgs.push_back("-mrelocation-model");
-    CmdArgs.push_back(Model);
-  }
+    CmdArgs.push_back("dynamic-no-pic");
 
-  // Infer the __PIC__ and __PIE__ values.
-  if (ModelStr == "pic" && PICForPIE) {
-    CmdArgs.push_back("-pic-level");
-    CmdArgs.push_back((LastPIEArg &&
-                      LastPIEArg->getOption().matches(options::OPT_fPIE)) ?
-                      "2" : "1");
-    CmdArgs.push_back("-pie-level");
-    CmdArgs.push_back((LastPIEArg &&
-                       LastPIEArg->getOption().matches(options::OPT_fPIE)) ?
-                      "2" : "1");
-  } else if (ModelStr == "pic" || ModelStr == "dynamic-no-pic") {
-    CmdArgs.push_back("-pic-level");
-    CmdArgs.push_back(((ModelStr != "dynamic-no-pic" && LastPICArg &&
-                        LastPICArg->getOption().matches(options::OPT_fPIC)) ||
-                       getToolChain().getTriple().isOSDarwin()) ? "2" : "1");
+    // Only a forced PIC mode can cause the actual compile to have PIC defines
+    // etc., no flags are sufficient. This behavior was selected to closely
+    // match that of llvm-gcc and Apple GCC before that.
+    if (getToolChain().isPICDefault() && getToolChain().isPICDefaultForced()) {
+      CmdArgs.push_back("-pic-level");
+      CmdArgs.push_back("2");
+    }
+  } else {
+    // Currently, LLVM only knows about PIC vs. static; the PIE differences are
+    // handled in Clang's IRGen by the -pie-level flag.
+    CmdArgs.push_back("-mrelocation-model");
+    CmdArgs.push_back(PIC ? "pic" : "static");
+
+    if (PIC) {
+      CmdArgs.push_back("-pic-level");
+      CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
+      if (PIE) {
+        CmdArgs.push_back("-pie-level");
+        CmdArgs.push_back(IsPICLevelTwo ? "2" : "1");
+      }
+    }
   }
 
   if (!Args.hasFlag(options::OPT_fmerge_all_constants,

Modified: cfe/trunk/lib/Driver/WindowsToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/WindowsToolChain.cpp?rev=168297&r1=168296&r2=168297&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/WindowsToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/WindowsToolChain.cpp Sun Nov 18 21:52:03 2012
@@ -84,14 +84,12 @@
   return getArch() == llvm::Triple::x86_64;
 }
 
-const char *Windows::GetDefaultRelocationModel() const {
-  return "static";
+bool Windows::isPICDefault() const {
+  return getArch() == llvm::Triple::x86_64;
 }
 
-const char *Windows::GetForcedPicModel() const {
-  if (getArch() == llvm::Triple::x86_64)
-    return "pic";
-  return 0;
+bool Windows::isPICDefaultForced() const {
+  return getArch() == llvm::Triple::x86_64;
 }
 
 // FIXME: This probably should goto to some platform utils place.

Modified: cfe/trunk/test/Driver/pic.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/pic.c?rev=168297&r1=168296&r2=168297&view=diff
==============================================================================
--- cfe/trunk/test/Driver/pic.c (original)
+++ cfe/trunk/test/Driver/pic.c Sun Nov 18 21:52:03 2012
@@ -5,28 +5,34 @@
 // CHECK-NO-PIC-NOT: "-pic-level"
 // CHECK-NO-PIC-NOT: "-pie-level"
 //
-// CHECK-DYNAMIC-NO-PIC1: "-mrelocation-model" "dynamic-no-pic"
-// CHECK-DYNAMIC-NO-PIC1: "-pic-level" "1"
-//
-// CHECK-DYNAMIC-NO-PIC2: "-mrelocation-model" "dynamic-no-pic"
-// CHECK-DYNAMIC-NO-PIC2: "-pic-level" "2"
-//
-// CHECK-PIC1-NOT: "-mrelocation-model"
+// CHECK-PIC1: "-mrelocation-model" "pic"
 // CHECK-PIC1: "-pic-level" "1"
 //
-// CHECK-PIC2-NOT: "-mrelocation-model"
+// CHECK-PIC2: "-mrelocation-model" "pic"
 // CHECK-PIC2: "-pic-level" "2"
 //
-// CHECK-PIE1-NOT: "-mrelocation-model"
+// CHECK-PIE1: "-mrelocation-model" "pic"
+// CHECK-PIE1: "-pic-level" "1"
 // CHECK-PIE1: "-pie-level" "1"
 //
-// CHECK-PIE2-NOT: "-mrelocation-model"
+// CHECK-PIE2: "-mrelocation-model" "pic"
+// CHECK-PIE2: "-pic-level" "2"
 // CHECK-PIE2: "-pie-level" "2"
 //
-// CHECK-PIE3: "{{.*}}ld{{(.exe)?}}"
-// CHECK-PIE3: "-pie"
-// CHECK-PIE3: "Scrt1.o" "crti.o" "crtbeginS.o"
-// CHECK-PIE3: "crtendS.o" "crtn.o"
+// CHECK-PIE-LD: "{{.*}}ld{{(.exe)?}}"
+// CHECK-PIE-LD: "-pie"
+// CHECK-PIE-LD: "Scrt1.o" "crti.o" "crtbeginS.o"
+// CHECK-PIE-LD: "crtendS.o" "crtn.o"
+//
+// CHECK-DYNAMIC-NO-PIC-32: "-mrelocation-model" "dynamic-no-pic"
+// CHECK-DYNAMIC-NO-PIC-32-NOT: "-pic-level"
+// CHECK-DYNAMIC-NO-PIC-32-NOT: "-pie-level"
+//
+// CHECK-DYNAMIC-NO-PIC-64: "-mrelocation-model" "dynamic-no-pic"
+// CHECK-DYNAMIC-NO-PIC-64: "-pic-level" "2"
+// CHECK-DYNAMIC-NO-PIC-64-NOT: "-pie-level"
+//
+// CHECK-NON-DARWIN-DYNAMIC-NO-PIC: error: unsupported option '-mdynamic-no-pic' for target 'i386-unknown-unknown'
 //
 // RUN: %clang -c %s -target i386-unknown-unknown -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
@@ -38,107 +44,141 @@
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
 // RUN: %clang -c %s -target i386-unknown-unknown -fPIE -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
+//
+// Check that PIC and PIE flags obey last-match-wins. If the last flag is
+// a no-* variant, regardless of which variant or which flags precede it, we
+// get no PIC.
 // RUN: %clang -c %s -target i386-unknown-unknown -fpic -fno-pic -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fno-PIC -### 2>&1 \
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fno-pic -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-pic -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fno-pic -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
 // RUN: %clang -c %s -target i386-unknown-unknown -fpic -fno-PIC -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fno-pic -### 2>&1 \
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fno-PIC -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-PIC -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fno-PIC -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fno-pie -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fno-pie -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
 // RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-pie -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fno-PIE -### 2>&1 \
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fno-pie -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fno-PIE -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fno-PIE -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
 // RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-PIE -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fno-pie -### 2>&1 \
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fno-PIE -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
-// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-pic -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
-// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fno-pic -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
-// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fno-pie -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
-// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIC -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fpic -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
-// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIE -fpie -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
-// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIC -fPIE -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
 //
-// Cases where both pic and pie are specified
-// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fpie -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
-// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fpie -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
+// Last-match-wins where both pic and pie are specified.
 // RUN: %clang -c %s -target i386-unknown-unknown -fpie -fpic -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
-// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fpic -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
-// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIE -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
-// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIE -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
-// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIC -### 2>&1 \
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fpic -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
 // RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIC -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
-// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIE -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
-// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIE -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fpie -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fPIC -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fpie -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
 // RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fpie -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fPIE -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIE -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
 // RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fPIE -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fpic -### 2>&1 \
+//
+// Last-match-wins when selecting level 1 vs. level 2.
+// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIC -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fpic -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fpie -### 2>&1 \
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -fpic -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIC1
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fpie -### 2>&1 \
+// RUN: %clang -c %s -target i386-unknown-unknown -fpic -fPIE -fpie -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIE1
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fPIC -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
-// RUN: %clang -c %s -target i386-unknown-unknown -fPIE -fPIC -### 2>&1 \
+// RUN: %clang -c %s -target i386-unknown-unknown -fpie -fPIC -fPIE -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIE2
 //
-// Defaults change for Darwin.
-// RUN: %clang -c %s -target i386-apple-darwin -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
-// RUN: %clang -c %s -target i386-apple-darwin -fno-pic -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
-// RUN: %clang -c %s -target i386-apple-darwin -fno-PIC -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
-//
 // Make sure -pie is passed to along to ld and that the right *crt* files
 // are linked in.
 // RUN: %clang %s -target i386-unknown-freebsd -fPIE -pie -### \
 // RUN: --sysroot=%S/Inputs/basic_freebsd_tree 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE3
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE-LD
 // RUN: %clang %s -target i386-linux-gnu -fPIE -pie -### \
 // RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-PIE3
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE-LD
+// RUN: %clang %s -target i386-linux-gnu -fPIC -pie -### \
+// RUN: --sysroot=%S/Inputs/basic_linux_tree 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIE-LD
 //
 // Disregard any of the PIC-specific flags if we have a trump-card flag.
 // RUN: %clang -c %s -target i386-unknown-unknown -mkernel -fPIC -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
 // RUN: %clang -c %s -target i386-unknown-unknown -static -fPIC -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
-// RUN: %clang -c %s -target i386-unknown-unknown -mdynamic-no-pic -fPIC -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC1
-// RUN: %clang -c %s -target i386-apple-darwin -mdynamic-no-pic -fPIC -### 2>&1 \
-// RUN:   | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC2
-
-// Checks for ARM
+//
+// Darwin is a beautiful and unique snowflake when it comes to these flags.
+// When targetting a 32-bit darwin system, the -fno-* flag variants work and
+// disable PIC, but any other flag enables PIC (*not* PIE) even if the flag
+// specifies PIE. On 64-bit targets, there is simply nothing you can do, there
+// is no PIE, there is only PIC when it comes to compilation.
+// RUN: %clang -c %s -target i386-apple-darwin -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i386-apple-darwin -fpic -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i386-apple-darwin -fPIC -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i386-apple-darwin -fpie -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i386-apple-darwin -fPIE -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i386-apple-darwin -fno-PIC -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-apple-darwin -fno-PIE -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-apple-darwin -fno-PIC -fpic -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i386-apple-darwin -fno-PIC -fPIE -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target x86_64-apple-darwin -fno-PIC -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target x86_64-apple-darwin -fno-PIE -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target x86_64-apple-darwin -fpic -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target x86_64-apple-darwin -fPIE -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
+//
+// Darwin gets even more special with '-mdynamic-no-pic'. This flag is only
+// valid on Darwin, and it's behavior is very strange but needs to remain
+// consistent for compatibility.
+// RUN: %clang -c %s -target i386-unknown-unknown -mdynamic-no-pic -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-NON-DARWIN-DYNAMIC-NO-PIC
+// RUN: %clang -c %s -target i386-apple-darwin -mdynamic-no-pic -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC-32
+// RUN: %clang -c %s -target i386-apple-darwin -mdynamic-no-pic -fno-pic -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC-32
+// RUN: %clang -c %s -target i386-apple-darwin -mdynamic-no-pic -fpie -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC-32
+// RUN: %clang -c %s -target x86_64-apple-darwin -mdynamic-no-pic -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC-64
+// RUN: %clang -c %s -target x86_64-apple-darwin -mdynamic-no-pic -fno-pic -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC-64
+// RUN: %clang -c %s -target x86_64-apple-darwin -mdynamic-no-pic -fpie -### 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-DYNAMIC-NO-PIC-64
+//
+// Checks for ARM+Apple+IOS including -fapple-kext, -mkernel, and iphoneos
+// version boundaries.
 // RUN: %clang -c %s -target armv7-apple-ios -fapple-kext -miphoneos-version-min=6.0.0 -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-PIC2
 // RUN: %clang -c %s -target armv7-apple-ios -mkernel -miphoneos-version-min=6.0.0 -### 2>&1 \





More information about the cfe-commits mailing list