diff options
author | Pawel Wodnicki <pawel@32bitmicro.com> | 2012-11-21 07:56:23 +0000 |
---|---|---|
committer | Pawel Wodnicki <pawel@32bitmicro.com> | 2012-11-21 07:56:23 +0000 |
commit | 0d803938d530e9c0dc3dac04bc012aef707987f0 (patch) | |
tree | 7e098709b04a06fa74e092fea75a38f167658c3f | |
parent | b47e89cddbc9426a44a29325de289f1a1f26cbbd (diff) | |
download | llvm-0d803938d530e9c0dc3dac04bc012aef707987f0.zip llvm-0d803938d530e9c0dc3dac04bc012aef707987f0.tar.gz llvm-0d803938d530e9c0dc3dac04bc012aef707987f0.tar.bz2 |
Merging r168297 into 3.2 release branch
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.
llvm-svn: 168416
-rw-r--r-- | clang/include/clang/Basic/DiagnosticDriverKinds.td | 2 | ||||
-rw-r--r-- | clang/include/clang/Driver/ToolChain.h | 15 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains.cpp | 38 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains.h | 22 | ||||
-rw-r--r-- | clang/lib/Driver/Tools.cpp | 143 | ||||
-rw-r--r-- | clang/lib/Driver/WindowsToolChain.cpp | 10 | ||||
-rw-r--r-- | clang/test/Driver/pic.c | 48 |
7 files changed, 172 insertions, 106 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index fe0be42..4b43035 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -11,6 +11,8 @@ let Component = "Driver" in { 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< diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 71736d6..919e880 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -172,14 +172,13 @@ public: /// 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; } diff --git a/clang/lib/Driver/ToolChains.cpp b/clang/lib/Driver/ToolChains.cpp index 819907b..a2ccb35 100644 --- a/clang/lib/Driver/ToolChains.cpp +++ b/clang/lib/Driver/ToolChains.cpp @@ -869,14 +869,12 @@ bool Darwin::UseSjLjExceptions() const { 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 { @@ -1378,13 +1376,14 @@ bool Generic_GCC::IsUnwindTablesDefault() const { 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) @@ -1438,14 +1437,13 @@ Tool &Hexagon_TC::SelectTool(const Compilation &C, 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. @@ -1470,12 +1468,12 @@ bool TCEToolChain::IsMathErrnoDefault() const { 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, diff --git a/clang/lib/Driver/ToolChains.h b/clang/lib/Driver/ToolChains.h index 8ea466a..9ef0277 100644 --- a/clang/lib/Driver/ToolChains.h +++ b/clang/lib/Driver/ToolChains.h @@ -129,8 +129,8 @@ public: 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 @@ public: 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. @@ -340,8 +340,8 @@ public: 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; @@ -389,7 +389,7 @@ public: 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 { @@ -530,8 +530,8 @@ public: 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; @@ -553,8 +553,8 @@ public: 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; diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index d420784..e37959b 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1769,30 +1769,46 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, 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, - options::OPT_fPIE, options::OPT_fno_PIE, - options::OPT_fpie, options::OPT_fno_pie); - bool PICDisabled = false; - bool PICEnabled = false; - bool PICForPIE = false; - if (LastPICArg) { - PICForPIE = (LastPICArg->getOption().matches(options::OPT_fPIE) || - LastPICArg->getOption().matches(options::OPT_fpie)); - PICEnabled = (PICForPIE || - LastPICArg->getOption().matches(options::OPT_fPIC) || - LastPICArg->getOption().matches(options::OPT_fpic)); - 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); @@ -1800,40 +1816,43 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, 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); - - // 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); - } + 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(); - // Infer the __PIC__ and __PIE__ values. - if (ModelStr == "pic" && PICForPIE) { - CmdArgs.push_back("-pie-level"); - CmdArgs.push_back((LastPICArg && - LastPICArg->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"); + // FIXME: Warn when this flag trumps some other PIC or PIE flag. + + CmdArgs.push_back("-mrelocation-model"); + CmdArgs.push_back("dynamic-no-pic"); + + // 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, @@ -2715,6 +2734,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fobjc-default-synthesize-properties"); } + // -fencode-extended-block-signature=1 is default. + if (getToolChain().IsEncodeExtendedBlockSignatureDefault()) { + CmdArgs.push_back("-fencode-extended-block-signature"); + } + // Allow -fno-objc-arr to trump -fobjc-arr/-fobjc-arc. // NOTE: This logic is duplicated in ToolChains.cpp. bool ARC = isObjCAutoRefCount(Args); @@ -4686,10 +4710,11 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_L); SanitizerArgs Sanitize(getToolChain().getDriver(), Args); - // If we're building a dynamic lib with -fsanitize=address, unresolved - // symbols may appear. Mark all of them as dynamic_lookup. - // Linking executables is handled in lib/Driver/ToolChains.cpp. - if (Sanitize.needsAsanRt()) { + // If we're building a dynamic lib with -fsanitize=address, or + // -fsanitize=undefined, unresolved symbols may appear. Mark all + // of them as dynamic_lookup. Linking executables is handled in + // lib/Driver/ToolChains.cpp. + if (Sanitize.needsAsanRt() || Sanitize.needsUbsanRt()) { if (Args.hasArg(options::OPT_dynamiclib) || Args.hasArg(options::OPT_bundle)) { CmdArgs.push_back("-undefined"); diff --git a/clang/lib/Driver/WindowsToolChain.cpp b/clang/lib/Driver/WindowsToolChain.cpp index ac65187..de2d535 100644 --- a/clang/lib/Driver/WindowsToolChain.cpp +++ b/clang/lib/Driver/WindowsToolChain.cpp @@ -84,14 +84,12 @@ bool Windows::IsUnwindTablesDefault() const { 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. diff --git a/clang/test/Driver/pic.c b/clang/test/Driver/pic.c index 5b69dba..efe525e 100644 --- a/clang/test/Driver/pic.c +++ b/clang/test/Driver/pic.c @@ -55,9 +55,11 @@ // 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-NO-PIC +// 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-NO-PIC +// 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 \ @@ -67,6 +69,48 @@ // 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 +// 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: | 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 -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 -fPIE -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: | FileCheck %s --check-prefix=CHECK-PIC1 +// RUN: %clang -c %s -target i386-unknown-unknown -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: | 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 |