aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/LangOptions.def3
-rw-r--r--include/clang/Driver/CC1Options.td2
-rw-r--r--include/clang/Driver/Options.td10
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp2
-rw-r--r--lib/Driver/Tools.cpp66
-rw-r--r--lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--lib/Frontend/InitPreprocessor.cpp4
-rw-r--r--test/Driver/fno-pic.c5
-rw-r--r--test/Driver/pic.c81
-rw-r--r--test/Preprocessor/pic.c22
10 files changed, 168 insertions, 30 deletions
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index a1ba2daf08..d2ce7c0df6 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -96,7 +96,8 @@ LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
VALUE_LANGOPT(PackStruct , 32, 0,
"default struct packing maximum alignment")
-VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level")
+VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level")
+VALUE_LANGOPT(PIELevel , 2, 0, "__PIE__ level")
LANGOPT(GNUInline , 1, 0, "GNU inline semantics")
LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro")
LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro")
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 18caca6df1..3ab8f83481 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -632,6 +632,8 @@ def fwrapv : Flag<"-fwrapv">,
HelpText<"Treat signed integer overflow as two's complement">;
def pic_level : Separate<"-pic-level">,
HelpText<"Value for __PIC__">;
+def pie_level : Separate<"-pie-level">,
+ HelpText<"Value for __PIE__">;
def pthread : Flag<"-pthread">,
HelpText<"Support POSIX threads in generated code">;
def fpack_struct : Separate<"-fpack-struct">,
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 7875eae4b7..1b6b20c6b3 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -265,8 +265,8 @@ def exported__symbols__list : Separate<"-exported_symbols_list">;
def e : JoinedOrSeparate<"-e">;
def fPIC : Flag<"-fPIC">, Group<f_Group>;
def fno_PIC : Flag<"-fno-PIC">, Group<f_Group>;
-def fPIE : Flag<"-fPIE">, Group<f_Group>, Flags<[NoArgumentUnused]>;
-def fno_PIE : Flag<"-fno-PIE">, Group<f_Group>, Flags<[NoArgumentUnused]>;
+def fPIE : Flag<"-fPIE">, Group<f_Group>;
+def fno_PIE : Flag<"-fno-PIE">, Group<f_Group>;
def faccess_control : Flag<"-faccess-control">, Group<f_Group>;
def fallow_unsupported : Flag<"-fallow-unsupported">, Group<f_Group>;
def faltivec : Flag<"-faltivec">, Group<f_Group>;
@@ -499,8 +499,8 @@ def fpascal_strings : Flag<"-fpascal-strings">, Group<f_Group>;
def fpch_preprocess : Flag<"-fpch-preprocess">, Group<f_Group>;
def fpic : Flag<"-fpic">, Group<f_Group>;
def fno_pic : Flag<"-fno-pic">, Group<f_Group>;
-def fpie : Flag<"-fpie">, Group<f_Group>, Flags<[NoArgumentUnused]>;
-def fno_pie : Flag<"-fno-pie">, Group<f_Group>, Flags<[NoArgumentUnused]>;
+def fpie : Flag<"-fpie">, Group<f_Group>;
+def fno_pie : Flag<"-fno-pie">, Group<f_Group>;
def fprofile_arcs : Flag<"-fprofile-arcs">, Group<f_Group>;
def fprofile_generate : Flag<"-fprofile-generate">, Group<f_Group>;
def framework : Separate<"-framework">, Flags<[LinkerInput]>;
@@ -605,7 +605,7 @@ def march_EQ : Joined<"-march=">, Group<m_Group>;
def mcmodel_EQ : Joined<"-mcmodel=">, Group<m_Group>;
def mconstant_cfstrings : Flag<"-mconstant-cfstrings">, Group<clang_ignored_m_Group>;
def mcpu_EQ : Joined<"-mcpu=">, Group<m_Group>;
-def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>, Flags<[NoArgumentUnused]>;
+def mdynamic_no_pic : Joined<"-mdynamic-no-pic">, Group<m_Group>;
def mfix_and_continue : Flag<"-mfix-and-continue">, Group<clang_ignored_m_Group>;
def mfloat_abi_EQ : Joined<"-mfloat-abi=">, Group<m_Group>;
def mfpmath_EQ : Joined<"-mfpmath=">, Group<m_Group>;
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 68895dd93e..db0bd951c1 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -2594,7 +2594,7 @@ llvm::GlobalVariable *CGObjCGNU::ObjCIvarOffsetVariable(
// to replace it with the real version for a library. In non-PIC code you
// must compile with the fragile ABI if you want to use ivars from a
// GCC-compiled class.
- if (CGM.getLangOpts().PICLevel) {
+ if (CGM.getLangOpts().PICLevel || CGM.getLangOpts().PIELevel) {
llvm::GlobalVariable *IvarOffsetGV = new llvm::GlobalVariable(TheModule,
Int32Ty, false,
llvm::GlobalValue::PrivateLinkage, OffsetGuess, Name+".guess");
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index fd064d5bb5..14842f36e7 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1480,19 +1480,43 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// would do to enable flag_pic.
//
// FIXME: Centralize this code.
- bool PICEnabled = (Args.hasArg(options::OPT_fPIC) ||
- Args.hasArg(options::OPT_fpic) ||
- Args.hasArg(options::OPT_fPIE) ||
- Args.hasArg(options::OPT_fpie));
- bool PICDisabled = (Args.hasArg(options::OPT_mkernel) ||
- Args.hasArg(options::OPT_static) ||
- Args.hasArg(options::OPT_fno_PIC) ||
- Args.hasArg(options::OPT_fno_pic) ||
- Args.hasArg(options::OPT_fno_PIE) ||
- Args.hasArg(options::OPT_fno_pie));
+ Arg *LastPICArg = 0;
+ for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
+ if ((*I)->getOption().matches(options::OPT_fPIC) ||
+ (*I)->getOption().matches(options::OPT_fno_PIC) ||
+ (*I)->getOption().matches(options::OPT_fpic) ||
+ (*I)->getOption().matches(options::OPT_fno_pic) ||
+ (*I)->getOption().matches(options::OPT_fPIE) ||
+ (*I)->getOption().matches(options::OPT_fno_PIE) ||
+ (*I)->getOption().matches(options::OPT_fpie) ||
+ (*I)->getOption().matches(options::OPT_fno_pie)) {
+ LastPICArg = *I;
+ (*I)->claim();
+ }
+ }
+ 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;
+ }
+ // 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.
+ if (Args.hasArg(options::OPT_mkernel))
+ PICDisabled = true;
+ 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 (Args.hasArg(options::OPT_mdynamic_no_pic))
+ if (DynamicNoPIC)
Model = "dynamic-no-pic";
else if (PICDisabled)
Model = "static";
@@ -1501,19 +1525,25 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
else
Model = getToolChain().GetDefaultRelocationModel();
}
- if (StringRef(Model) != "pic") {
+ StringRef ModelStr = Model ? Model : "";
+ if (Model && ModelStr != "pic") {
CmdArgs.push_back("-mrelocation-model");
CmdArgs.push_back(Model);
}
- // Infer the __PIC__ value.
- //
- // FIXME: This isn't quite right on Darwin, which always sets
- // __PIC__=2.
- if (strcmp(Model, "pic") == 0 || strcmp(Model, "dynamic-no-pic") == 0) {
+ // 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(Args.hasArg(options::OPT_fPIC) ? "2" : "1");
+ CmdArgs.push_back(((ModelStr != "dynamic-no-pic" && LastPICArg &&
+ LastPICArg->getOption().matches(options::OPT_fPIC)) ||
+ getToolChain().getTriple().isOSDarwin()) ? "2" : "1");
}
+
if (!Args.hasFlag(options::OPT_fmerge_all_constants,
options::OPT_fno_merge_all_constants))
CmdArgs.push_back("-fno-merge-all-constants");
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 6e36242be2..02947c778c 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -740,6 +740,8 @@ static void LangOptsToArgs(const LangOptions &Opts, ToArgsList &Res) {
Res.push_back("-fno-bitfield-type-alignment");
if (Opts.PICLevel)
Res.push_back("-pic-level", llvm::utostr(Opts.PICLevel));
+ if (Opts.PIELevel)
+ Res.push_back("-pie-level", llvm::utostr(Opts.PIELevel));
if (Opts.ObjCGCBitmapPrint)
Res.push_back("-print-ivar-layout");
if (Opts.NoConstantCFStrings)
@@ -1897,6 +1899,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
Opts.PackStruct = Args.getLastArgIntValue(OPT_fpack_struct, 0, Diags);
Opts.PICLevel = Args.getLastArgIntValue(OPT_pic_level, 0, Diags);
+ Opts.PIELevel = Args.getLastArgIntValue(OPT_pie_level, 0, Diags);
Opts.Static = Args.hasArg(OPT_static_define);
Opts.DumpRecordLayoutsSimple = Args.hasArg(OPT_fdump_record_layouts_simple);
Opts.DumpRecordLayouts = Opts.DumpRecordLayoutsSimple
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 37e89173ab..c1b9d57f09 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -528,6 +528,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("__PIC__", Twine(PICLevel));
Builder.defineMacro("__pic__", Twine(PICLevel));
}
+ if (unsigned PIELevel = LangOpts.PIELevel) {
+ Builder.defineMacro("__PIE__", Twine(PIELevel));
+ Builder.defineMacro("__pie__", Twine(PIELevel));
+ }
// Macros to control C99 numerics and <float.h>
Builder.defineMacro("__FLT_EVAL_METHOD__", Twine(TI.getFloatEvalMethod()));
diff --git a/test/Driver/fno-pic.c b/test/Driver/fno-pic.c
deleted file mode 100644
index 5ec122850d..0000000000
--- a/test/Driver/fno-pic.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: %clang -c %s -target i386-apple-darwin -### 2>&1 | FileCheck %s --check-prefix=PIC_ON_BY_DEFAULT
-// PIC_ON_BY_DEFAULT: "-pic-level" "1"
-
-// RUN: %clang -c %s -target i386-apple-darwin -### -fno-pic 2>&1 | FileCheck %s --check-prefix=FNO_PIC
-// FNO_PIC: "-mrelocation-model" "static"
diff --git a/test/Driver/pic.c b/test/Driver/pic.c
new file mode 100644
index 0000000000..3952f85ceb
--- /dev/null
+++ b/test/Driver/pic.c
@@ -0,0 +1,81 @@
+// Test the driver's control over the PIC behavior. These consist of tests of
+// the relocation model flags and the pic level flags passed to CC1.
+//
+// CHECK-NO-PIC: "-mrelocation-model" "static"
+// 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: "-pic-level" "1"
+//
+// CHECK-PIC2-NOT: "-mrelocation-model"
+// CHECK-PIC2: "-pic-level" "2"
+//
+// CHECK-PIE1-NOT: "-mrelocation-model"
+// CHECK-PIE1: "-pie-level" "1"
+//
+// CHECK-PIE2-NOT: "-mrelocation-model"
+// CHECK-PIE2: "-pie-level" "2"
+//
+// RUN: %clang -c %s -target i386-unknown-unknown -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC
+// RUN: %clang -c %s -target i386-unknown-unknown -fpic -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIC1
+// RUN: %clang -c %s -target i386-unknown-unknown -fPIC -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-PIC2
+// RUN: %clang -c %s -target i386-unknown-unknown -fpie -### 2>&1 \
+// 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
+// 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: | 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: | 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: | 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: | 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 -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
+//
+// 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
+//
+// 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
diff --git a/test/Preprocessor/pic.c b/test/Preprocessor/pic.c
index 4597f4301f..3e649ee5ea 100644
--- a/test/Preprocessor/pic.c
+++ b/test/Preprocessor/pic.c
@@ -1,12 +1,34 @@
// RUN: %clang_cc1 -dM -E -o - %s \
// RUN: | FileCheck %s
// CHECK-NOT: #define __PIC__
+// CHECK-NOT: #define __PIE__
// CHECK-NOT: #define __pic__
+// CHECK-NOT: #define __pie__
+//
// RUN: %clang_cc1 -pic-level 1 -dM -E -o - %s \
// RUN: | FileCheck --check-prefix=CHECK-PIC1 %s
// CHECK-PIC1: #define __PIC__ 1
+// CHECK-PIC1-NOT: #define __PIE__
// CHECK-PIC1: #define __pic__ 1
+// CHECK-PIC1-NOT: #define __pie__
+//
// RUN: %clang_cc1 -pic-level 2 -dM -E -o - %s \
// RUN: | FileCheck --check-prefix=CHECK-PIC2 %s
// CHECK-PIC2: #define __PIC__ 2
+// CHECK-PIC2-NOT: #define __PIE__
// CHECK-PIC2: #define __pic__ 2
+// CHECK-PIC2-NOT: #define __pie__
+//
+// RUN: %clang_cc1 -pie-level 1 -dM -E -o - %s \
+// RUN: | FileCheck --check-prefix=CHECK-PIE1 %s
+// CHECK-PIE1-NOT: #define __PIC__
+// CHECK-PIE1: #define __PIE__ 1
+// CHECK-PIE1-NOT: #define __pic__
+// CHECK-PIE1: #define __pie__ 1
+//
+// RUN: %clang_cc1 -pie-level 2 -dM -E -o - %s \
+// RUN: | FileCheck --check-prefix=CHECK-PIE2 %s
+// CHECK-PIE2-NOT: #define __PIC__
+// CHECK-PIE2: #define __PIE__ 2
+// CHECK-PIE2-NOT: #define __pic__
+// CHECK-PIE2: #define __pie__ 2