diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index 6b113bc1c980a6586dd3ff1647453ae2040288ad..9ab35ff83c2464ee7910e4a74c228d3d14a3691a 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -1779,18 +1779,26 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // 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_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 (LastPICArg) { - PICForPIE = (LastPICArg->getOption().matches(options::OPT_fPIE) || - LastPICArg->getOption().matches(options::OPT_fpie)); + 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; } // Note that these flags are trump-cards. Regardless of the order w.r.t. the @@ -1825,9 +1833,13 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // 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((LastPICArg && - LastPICArg->getOption().matches(options::OPT_fPIE)) ? + 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"); diff --git a/clang/test/Driver/pic.c b/clang/test/Driver/pic.c index 5b69dba36df7d627c7538ee01332981a69440988..efe525e555a4b9771f7da48714022a34e4a8e1cc 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