diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -678,4 +678,7 @@ def err_drv_invalid_empty_dxil_validator_version : Error< "invalid validator version : %0\n" "If validator major version is 0, minor version must also be 0.">; + +def err_drv_riscv_unsupported_with_linker_relaxation : Error< + "%0 is unsupported with RISC-V linker relaxation (-mrelax)">; } diff --git a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp --- a/clang/lib/Driver/ToolChains/Arch/RISCV.cpp +++ b/clang/lib/Driver/ToolChains/Arch/RISCV.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "RISCV.h" +#include "../Clang.h" #include "ToolChains/CommonArgs.h" #include "clang/Basic/CharInfo.h" #include "clang/Driver/Driver.h" @@ -137,10 +138,17 @@ Features.push_back("+reserve-x31"); // -mrelax is default, unless -mno-relax is specified. - if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) + if (Args.hasFlag(options::OPT_mrelax, options::OPT_mno_relax, true)) { Features.push_back("+relax"); - else + // -gsplit-dwarf -mrelax requires DW_AT_high_pc/DW_AT_ranges/... indexing + // into .debug_addr, which is currently not implemented. + Arg *A; + if (getDebugFissionKind(D, Args, A) != DwarfFissionKind::None) + D.Diag(clang::diag::err_drv_riscv_unsupported_with_linker_relaxation) + << A->getAsString(Args); + } else { Features.push_back("-relax"); + } // GCC Compatibility: -mno-save-restore is default, unless -msave-restore is // specified. diff --git a/clang/lib/Driver/ToolChains/Clang.h b/clang/lib/Driver/ToolChains/Clang.h --- a/clang/lib/Driver/ToolChains/Clang.h +++ b/clang/lib/Driver/ToolChains/Clang.h @@ -198,6 +198,12 @@ const char *LinkingOutput) const override; }; +enum class DwarfFissionKind { None, Split, Single }; + +DwarfFissionKind getDebugFissionKind(const Driver &D, + const llvm::opt::ArgList &Args, + llvm::opt::Arg *&Arg); + } // end namespace tools } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -4051,9 +4051,7 @@ options::OPT_fno_spell_checking); } -enum class DwarfFissionKind { None, Split, Single }; - -static DwarfFissionKind getDebugFissionKind(const Driver &D, +DwarfFissionKind tools::getDebugFissionKind(const Driver &D, const ArgList &Args, Arg *&Arg) { Arg = Args.getLastArg(options::OPT_gsplit_dwarf, options::OPT_gsplit_dwarf_EQ, options::OPT_gno_split_dwarf); diff --git a/clang/test/Driver/riscv-features.c b/clang/test/Driver/riscv-features.c --- a/clang/test/Driver/riscv-features.c +++ b/clang/test/Driver/riscv-features.c @@ -35,3 +35,10 @@ // RUN: not %clang -cc1 -triple riscv64-unknown-elf -target-feature +e 2>&1 | FileCheck %s -check-prefix=RV64-WITH-E // RV64-WITH-E: error: invalid feature combination: standard user-level extension 'e' requires 'rv32' + +// RUN: not %clang -c --target=riscv64-linux-gnu -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF +// RUN: not %clang -c --target=riscv64 -gsplit-dwarf=single %s 2>&1 | FileCheck %s --check-prefix=ERR-SPLIT-DWARF +// RUN: %clang -### -c --target=riscv64 -mno-relax -g -gsplit-dwarf %s 2>&1 | FileCheck %s --check-prefix=SPLIT-DWARF + +// ERR-SPLIT-DWARF: error: -gsplit-dwarf{{.*}} is unsupported with RISC-V linker relaxation (-mrelax) +// SPLIT-DWARF: "-split-dwarf-file"