[Driver] Define LinkOption and fix forwarded options to GCC for linking

Many driver options are neither 'DriverOption' nor 'LinkerInput'. When gcc is
used for linking, these options get forwarded even if they don't have anything
to do with linking. Among these options, clang-specific ones can cause gcc to
error.

Just use 'OPT_Link_Group' and a new flag 'LinkOption' for options which already
have a group.

gfortran support apparently bit rots (which does not seem to make much sense). XFAIL the test.
This commit is contained in:
Fangrui Song 2020-07-25 12:33:18 -07:00
parent 48c3228c5c
commit 6a75496836
5 changed files with 26 additions and 41 deletions

View File

@ -33,7 +33,8 @@ enum ClangFlags {
CC1Option = (1 << 10), CC1Option = (1 << 10),
CC1AsOption = (1 << 11), CC1AsOption = (1 << 11),
NoDriverOption = (1 << 12), NoDriverOption = (1 << 12),
Ignored = (1 << 13) LinkOption = (1 << 13),
Ignored = (1 << 14),
}; };
enum ID { enum ID {

View File

@ -52,6 +52,10 @@ def CC1AsOption : OptionFlag;
// NoDriverOption - This option should not be accepted by the driver. // NoDriverOption - This option should not be accepted by the driver.
def NoDriverOption : OptionFlag; def NoDriverOption : OptionFlag;
// If an option affects linking, but has a primary group (so Link_Group cannot
// be used), add this flag.
def LinkOption : OptionFlag;
// A short name to show in documentation. The name will be interpreted as rST. // A short name to show in documentation. The name will be interpreted as rST.
class DocName<string name> { string DocName = name; } class DocName<string name> { string DocName = name; }
@ -573,7 +577,7 @@ def config_system_dir_EQ : Joined<["--"], "config-system-dir=">, Flags<[DriverOp
HelpText<"System directory for configuration files">; HelpText<"System directory for configuration files">;
def config_user_dir_EQ : Joined<["--"], "config-user-dir=">, Flags<[DriverOption, HelpHidden]>, def config_user_dir_EQ : Joined<["--"], "config-user-dir=">, Flags<[DriverOption, HelpHidden]>,
HelpText<"User directory for configuration files">; HelpText<"User directory for configuration files">;
def coverage : Flag<["-", "--"], "coverage">, Flags<[CoreOption]>; def coverage : Flag<["-", "--"], "coverage">, Group<Link_Group>, Flags<[CoreOption]>;
def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>; def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>;
def current__version : JoinedOrSeparate<["-"], "current_version">; def current__version : JoinedOrSeparate<["-"], "current_version">;
def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>, def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>,
@ -1747,7 +1751,7 @@ def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">,
HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">; HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">;
defm preserve_as_comments : OptOutFFlag<"preserve-as-comments", "", defm preserve_as_comments : OptOutFFlag<"preserve-as-comments", "",
"Do not preserve comments in inline assembly">; "Do not preserve comments in inline assembly">;
def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group<f_Group>; def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group<f_Group>, Flags<[LinkOption]>;
def fno_profile_arcs : Flag<["-"], "fno-profile-arcs">, Group<f_Group>; def fno_profile_arcs : Flag<["-"], "fno-profile-arcs">, Group<f_Group>;
def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>; def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>;
def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group<clang_ignored_f_Group>; def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group<clang_ignored_f_Group>;
@ -2724,7 +2728,7 @@ def nostdinc : Flag<["-"], "nostdinc">, Flags<[CoreOption]>;
def nostdlibinc : Flag<["-"], "nostdlibinc">; def nostdlibinc : Flag<["-"], "nostdlibinc">;
def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>, def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>,
HelpText<"Disable standard #include directories for the C++ standard library">; HelpText<"Disable standard #include directories for the C++ standard library">;
def nostdlib : Flag<["-"], "nostdlib">; def nostdlib : Flag<["-"], "nostdlib">, Group<Link_Group>;
def nostdlibxx : Flag<["-"], "nostdlib++">; def nostdlibxx : Flag<["-"], "nostdlib++">;
def object : Flag<["-"], "object">; def object : Flag<["-"], "object">;
def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option, CC1AsOption]>, def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option, CC1AsOption]>,
@ -2768,15 +2772,15 @@ def pthread : Flag<["-"], "pthread">, Flags<[CC1Option]>,
HelpText<"Support POSIX threads in generated code">; HelpText<"Support POSIX threads in generated code">;
def no_pthread : Flag<["-"], "no-pthread">, Flags<[CC1Option]>; def no_pthread : Flag<["-"], "no-pthread">, Flags<[CC1Option]>;
def p : Flag<["-"], "p">; def p : Flag<["-"], "p">;
def pie : Flag<["-"], "pie">; def pie : Flag<["-"], "pie">, Group<Link_Group>;
def static_pie : Flag<["-"], "static-pie">; def static_pie : Flag<["-"], "static-pie">, Group<Link_Group>;
def read__only__relocs : Separate<["-"], "read_only_relocs">; def read__only__relocs : Separate<["-"], "read_only_relocs">;
def remap : Flag<["-"], "remap">; def remap : Flag<["-"], "remap">;
def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[DriverOption,CC1Option]>, def rewrite_objc : Flag<["-"], "rewrite-objc">, Flags<[DriverOption,CC1Option]>,
HelpText<"Rewrite Objective-C source to C++">, Group<Action_Group>; HelpText<"Rewrite Objective-C source to C++">, Group<Action_Group>;
def rewrite_legacy_objc : Flag<["-"], "rewrite-legacy-objc">, Flags<[DriverOption]>, def rewrite_legacy_objc : Flag<["-"], "rewrite-legacy-objc">, Flags<[DriverOption]>,
HelpText<"Rewrite Legacy Objective-C source to C++">; HelpText<"Rewrite Legacy Objective-C source to C++">;
def rdynamic : Flag<["-"], "rdynamic">; def rdynamic : Flag<["-"], "rdynamic">, Group<Link_Group>;
def resource_dir : Separate<["-"], "resource-dir">, def resource_dir : Separate<["-"], "resource-dir">,
Flags<[DriverOption, CC1Option, CoreOption, HelpHidden]>, Flags<[DriverOption, CC1Option, CoreOption, HelpHidden]>,
HelpText<"The directory which holds the compiler resource files">; HelpText<"The directory which holds the compiler resource files">;
@ -2818,13 +2822,13 @@ def segs__read__only__addr : Separate<["-"], "segs_read_only_addr">;
def segs__read__write__addr : Separate<["-"], "segs_read_write_addr">; def segs__read__write__addr : Separate<["-"], "segs_read_write_addr">;
def segs__read__ : Joined<["-"], "segs_read_">; def segs__read__ : Joined<["-"], "segs_read_">;
def shared_libgcc : Flag<["-"], "shared-libgcc">; def shared_libgcc : Flag<["-"], "shared-libgcc">;
def shared : Flag<["-", "--"], "shared">; def shared : Flag<["-", "--"], "shared">, Group<Link_Group>;
def single__module : Flag<["-"], "single_module">; def single__module : Flag<["-"], "single_module">;
def specs_EQ : Joined<["-", "--"], "specs=">; def specs_EQ : Joined<["-", "--"], "specs=">;
def specs : Separate<["-", "--"], "specs">, Flags<[Unsupported]>; def specs : Separate<["-", "--"], "specs">, Flags<[Unsupported]>;
def static_libgcc : Flag<["-"], "static-libgcc">; def static_libgcc : Flag<["-"], "static-libgcc">;
def static_libstdcxx : Flag<["-"], "static-libstdc++">; def static_libstdcxx : Flag<["-"], "static-libstdc++">;
def static : Flag<["-", "--"], "static">, Flags<[NoArgumentUnused]>; def static : Flag<["-", "--"], "static">, Group<Link_Group>, Flags<[NoArgumentUnused]>;
def std_default_EQ : Joined<["-"], "std-default=">; def std_default_EQ : Joined<["-"], "std-default=">;
def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>, def std_EQ : Joined<["-", "--"], "std=">, Flags<[CC1Option]>,
Group<CompileOnly_Group>, HelpText<"Language standard to compile for">, Group<CompileOnly_Group>, HelpText<"Language standard to compile for">,
@ -3283,8 +3287,8 @@ defm : BooleanFFlag<"keep-inline-functions">, Group<clang_ignored_gcc_optimizati
def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<f_Group>; def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<f_Group>;
def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>, Flags<[CoreOption]>; def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>, Flags<[CoreOption, LinkOption]>;
def ld_path_EQ : Joined<["--"], "ld-path=">; def ld_path_EQ : Joined<["--"], "ld-path=">, Group<Link_Group>;
defm align_labels : BooleanFFlag<"align-labels">, Group<clang_ignored_gcc_optimization_f_Group>; defm align_labels : BooleanFFlag<"align-labels">, Group<clang_ignored_gcc_optimization_f_Group>;
def falign_labels_EQ : Joined<["-"], "falign-labels=">, Group<clang_ignored_gcc_optimization_f_Group>; def falign_labels_EQ : Joined<["-"], "falign-labels=">, Group<clang_ignored_gcc_optimization_f_Group>;

View File

@ -38,10 +38,7 @@ using tools::addMultilibFlag;
using tools::addPathIfExists; using tools::addPathIfExists;
static bool forwardToGCC(const Option &O) { static bool forwardToGCC(const Option &O) {
// Don't forward inputs from the original command line. They are added from return O.matches(options::OPT_Link_Group) || O.hasFlag(options::LinkOption);
// InputInfoList.
return O.getKind() != Option::InputClass &&
!O.hasFlag(options::DriverOption) && !O.hasFlag(options::LinkerInput);
} }
// Switch CPU names not recognized by GNU assembler to a close CPU that it does // Switch CPU names not recognized by GNU assembler to a close CPU that it does
@ -76,23 +73,6 @@ void tools::gcc::Common::ConstructJob(Compilation &C, const JobAction &JA,
// to get to the assembler. // to get to the assembler.
A->claim(); A->claim();
// Don't forward any -g arguments to assembly steps.
if (isa<AssembleJobAction>(JA) &&
A->getOption().matches(options::OPT_g_Group))
continue;
// Don't forward any -W arguments to assembly and link steps.
if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) &&
A->getOption().matches(options::OPT_W_Group))
continue;
// Don't forward -mno-unaligned-access since GCC doesn't understand
// it and because it doesn't affect the assembly or link steps.
if ((isa<AssembleJobAction>(JA) || isa<LinkJobAction>(JA)) &&
(A->getOption().matches(options::OPT_munaligned_access) ||
A->getOption().matches(options::OPT_mno_unaligned_access)))
continue;
A->render(Args, CmdArgs); A->render(Args, CmdArgs);
} }
} }

View File

@ -1,3 +1,8 @@
// RUN: %clang -### %s -target aarch64-none-elf \
// RUN: --coverage -fuse-ld=lld --ld-path=ld -nostdlib -r -rdynamic -static -static-pie \
// RUN: 2>&1 | FileCheck --check-prefix=FORWARD %s
// FORWARD: gcc{{[^"]*}}" "--coverage" "-fuse-ld=lld" "--ld-path=ld" "-nostdlib" "-r" "-rdynamic" "-static" "-static-pie"
// Check that we don't try to forward -Xclang or -mlinker-version to GCC. // Check that we don't try to forward -Xclang or -mlinker-version to GCC.
// PR12920 -- Check also we may not forward W_Group options to GCC. // PR12920 -- Check also we may not forward W_Group options to GCC.
// //
@ -5,7 +10,7 @@
// RUN: %s \ // RUN: %s \
// RUN: -Wall -Wdocumentation \ // RUN: -Wall -Wdocumentation \
// RUN: -Xclang foo-bar \ // RUN: -Xclang foo-bar \
// RUN: -march=x86-64 \ // RUN: -pie -march=x86-64 \
// RUN: -mlinker-version=10 -### 2> %t // RUN: -mlinker-version=10 -### 2> %t
// RUN: FileCheck < %t %s // RUN: FileCheck < %t %s
// //
@ -15,13 +20,13 @@
// CHECK: "-o" "{{[^"]+}}.o" // CHECK: "-o" "{{[^"]+}}.o"
// //
// gcc as ld. // gcc as ld.
// CHECK: gcc{{[^"]*}}" // CHECK: gcc{{[^"]*}}" "-pie"
// CHECK-NOT: "-mlinker-version=10" // CHECK-NOT: "-mlinker-version=10"
// CHECK-NOT: "-Xclang" // CHECK-NOT: "-Xclang"
// CHECK-NOT: "foo-bar" // CHECK-NOT: "foo-bar"
// CHECK-NOT: "-Wall" // CHECK-NOT: "-Wall"
// CHECK-NOT: "-Wdocumentation" // CHECK-NOT: "-Wdocumentation"
// CHECK: -march // CHECK-NOT: -march
// CHECK-NOT: "-mlinker-version=10" // CHECK-NOT: "-mlinker-version=10"
// CHECK-NOT: "-Xclang" // CHECK-NOT: "-Xclang"
// CHECK-NOT: "foo-bar" // CHECK-NOT: "foo-bar"
@ -34,9 +39,3 @@
// RUN: | FileCheck --check-prefix=CHECK-ASM %s // RUN: | FileCheck --check-prefix=CHECK-ASM %s
// CHECK-ASM: as // CHECK-ASM: as
// CHECK-ASM-NOT: "-g" // CHECK-ASM-NOT: "-g"
// Check that we're not forwarding -mno-unaligned-access.
// RUN: %clang -target aarch64-none-elf -mno-unaligned-access %s -### 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-ARM %s
// CHECK-ARM: gcc{{[^"]*}}"
// CHECK-ARM-NOT: -mno-unaligned-access

View File

@ -1,3 +1,4 @@
! XFAIL: *
! Test that Clang can forward all of the flags which are documented as ! Test that Clang can forward all of the flags which are documented as
! being supported by gfortran to GCC when falling back to GCC for ! being supported by gfortran to GCC when falling back to GCC for
! a fortran input file. ! a fortran input file.