Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion amd/comgr/test-lit/comgr-sources/compile-hip-asan.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ int main(int argc, char *argv[]) {

amd_comgr_(create_action_info(&DataAction));
amd_comgr_(action_info_set_language(DataAction, AMD_COMGR_LANGUAGE_HIP));
amd_comgr_(action_info_set_isa_name(DataAction, "amdgcn-amd-amdhsa--gfx900"));
amd_comgr_(action_info_set_isa_name(DataAction, "amdgcn-amd-amdhsa--gfx900:xnack+"));
amd_comgr_(action_info_set_option_list(DataAction, CompileOptions,
CompileOptionsCount));
amd_comgr_(action_info_set_device_lib_linking(DataAction, true));
Expand Down
10 changes: 1 addition & 9 deletions clang/include/clang/Driver/RocmInstallationDetector.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,6 @@ class RocmInstallationDetector {
// Asan runtime library
SmallString<0> AsanRTL;

// OpenMP ASan runtime library
SmallString<0> OpenMPASanRTLPath;

// Libraries swapped based on compile flags.
ConditionalLibrary WavefrontSize64;
ConditionalLibrary FiniteOnly;
Expand Down Expand Up @@ -177,8 +174,7 @@ class RocmInstallationDetector {
public:
RocmInstallationDetector(const Driver &D, const llvm::Triple &HostTriple,
const llvm::opt::ArgList &Args,
bool DetectHIPRuntime = true,
bool DetectOpenMPRuntime = true);
bool DetectHIPRuntime = true);

/// Get file paths of default bitcode libraries common to AMDGPU based
/// toolchains.
Expand Down Expand Up @@ -240,9 +236,6 @@ class RocmInstallationDetector {
/// Returns empty string of Asan runtime library is not available.
StringRef getAsanRTLPath() const { return AsanRTL; }

/// Returns empty string of OpenMP Asan runtime library is not available.
StringRef getOpenMPASanRTLPath() const { return OpenMPASanRTLPath; }

StringRef getWavefrontSize64Path(bool Enabled) const {
return WavefrontSize64.get(Enabled);
}
Expand Down Expand Up @@ -275,7 +268,6 @@ class RocmInstallationDetector {

void detectDeviceLibrary();
void detectHIPRuntime();
void detectOpenMPRuntime();

/// Get the values for --rocm-device-lib-path arguments
ArrayRef<std::string> getRocmDeviceLibPathArg() const {
Expand Down
5 changes: 4 additions & 1 deletion clang/include/clang/Driver/SanitizerArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define LLVM_CLANG_DRIVER_SANITIZERARGS_H

#include "clang/Basic/Sanitizers.h"
#include "clang/Driver/Action.h"
#include "clang/Driver/Types.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
Expand Down Expand Up @@ -85,7 +86,9 @@ class SanitizerArgs {
public:
/// Parses the sanitizer arguments from an argument list.
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
bool DiagnoseErrors = true);
bool DiagnoseErrors = true, bool DiagnoseBoundArchErrors = true,
StringRef BoundArch = "",
Action::OffloadKind DeviceOffloadKind = Action::OFK_None);

bool needsSharedRt() const { return SharedRuntime; }
bool needsStableAbi() const { return StableABI; }
Expand Down
19 changes: 18 additions & 1 deletion clang/include/clang/Driver/ToolChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FloatingPointMode.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/Debug/Options.h"
Expand Down Expand Up @@ -186,8 +187,13 @@ class ToolChain {
Tool *getOffloadPackager() const;
Tool *getLinkerWrapper() const;

/// Track if diagnostics have been emitted for sanitizer arguments already to
/// avoid duplicate diagnostics.
mutable bool SanitizerArgsChecked = false;

/// Set of BoundArch values which have already had diagnostics emitted.
mutable llvm::SmallSet<StringRef, 4> BoundArchSanitizerArgsChecked;

/// The effective clang triple for the current Job.
mutable llvm::Triple EffectiveTriple;

Expand Down Expand Up @@ -343,7 +349,18 @@ class ToolChain {
/// -print-multi-flags-experimental argument.
Multilib::flags_list getMultilibFlags(const llvm::opt::ArgList &) const;

SanitizerArgs getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const;
SanitizerArgs getSanitizerArgs(
const llvm::opt::ArgList &JobArgs, StringRef BoundArch = "",
Action::OffloadKind DeviceOffloadKind = Action::OFK_None) const;

/// Returns the feature requirement for a sanitizer on a specific arch for
/// diagnostic purposes. Returns the required feature name (e.g., "xnack+") if
/// the sanitizer is generally supported but requires a specific feature for
/// the given BoundArch, or an empty StringRef otherwise.
virtual StringRef getSanitizerRequirement(SanitizerMask Kinds,
StringRef BoundArch) const {
return {};
}

const XRayArgs getXRayArgs(const llvm::opt::ArgList &) const;

Expand Down
94 changes: 84 additions & 10 deletions clang/lib/Driver/SanitizerArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,9 @@ bool SanitizerArgs::needsLTO() const {

SanitizerArgs::SanitizerArgs(const ToolChain &TC,
const llvm::opt::ArgList &Args,
bool DiagnoseErrors) {
bool DiagnoseErrors, bool DiagnoseBoundArchErrors,
StringRef BoundArch,
Action::OffloadKind DeviceOffloadKind) {
SanitizerMask AllRemove; // During the loop below, the accumulated set of
// sanitizers disabled by the current sanitizer
// argument or any argument after it.
Expand All @@ -412,8 +414,16 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
SanitizerMask IgnoreForUbsanFeature; // Accumulated set of values passed to
// `-fsanitize-ignore-for-ubsan-feature`.
SanitizerMask Kinds;
const SanitizerMask Supported =
setGroupBits(TC.getSupportedSanitizers("", Action::OFK_None));

// Figure out the base toolchain's sanitizer support so we can diagnose the
// diff for a specific BoundArch.
const SanitizerMask ToolChainSupported =
setGroupBits(TC.getSupportedSanitizers("", DeviceOffloadKind));

const SanitizerMask BoundArchSupported =
BoundArch.empty() ? ToolChainSupported
: setGroupBits(TC.getSupportedSanitizers(
BoundArch, DeviceOffloadKind));

CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
options::OPT_fno_sanitize_cfi_cross_dso, false);
Expand Down Expand Up @@ -540,15 +550,79 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
DiagnosedKinds |= SanitizerKind::CFIMFCall;
}

if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
if (DiagnoseErrors) {
std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
// Check for sanitizers that are supported by the toolchain but not for
// this specific arch (e.g., AMDGPU requires specific subtarget features
// for address sanitizer.)
if (SanitizerMask ArchSpecificUnsupported =
Add & ToolChainSupported & ~BoundArchSupported & ~DiagnosedKinds;
ArchSpecificUnsupported && DiagnoseBoundArchErrors) {
// Upgrade the warning to an error if the unsupported sanitizer was
// explicitly specified for the bound arch.

// FIXME: There are additional options which explicitly bind to this
// device.
bool IsExplicitDevice =
Arg->getBaseArg().getOption().matches(options::OPT_Xarch_device);

// Check if the toolchain provides a feature requirement hint for
// any of the unsupported sanitizers
StringRef Requirement =
TC.getSanitizerRequirement(ArchSpecificUnsupported, BoundArch);
if (!Requirement.empty()) {
// Emit diagnostic with feature requirement
//
// TODO: Use variant of unsupported_option_part_for_target that
// includes offload_arch_req_feature
D.Diag(
IsExplicitDevice
? diag::
err_drv_unsupported_option_for_offload_arch_req_feature
: diag::
warn_drv_unsupported_option_for_offload_arch_req_feature)
<< Arg->getAsString(Args) << BoundArch << Requirement;
} else {
// Fall back to generic diagnostic if no requirement was provided
SanitizerSet UnsupportedSet;
UnsupportedSet.Mask = ArchSpecificUnsupported;
D.Diag(diag::warn_drv_unsupported_option_part_for_target)
<< toString(UnsupportedSet) << Arg->getAsString(Args)
<< Triple.str();
}

DiagnosedKinds |= ArchSpecificUnsupported;
}

// Check for sanitizers that are not supported at all by the toolchain
if (SanitizerMask KindsToDiagnose =
Add & ~ToolChainSupported & ~DiagnosedKinds;
DiagnoseErrors && KindsToDiagnose) {
bool IsExplicitDevice =
Arg->getBaseArg().getOption().matches(options::OPT_Xarch_device);
// For device offload compilation, emit a warning since the sanitizer
// may still work on the host. For non-offload compilation or explicit
// device specification, emit an error.
if (DeviceOffloadKind != Action::OFK_None &&
DeviceOffloadKind != Action::OFK_Host) {
// For warnings, extract just the sanitizer names (e.g., "fuzzer")
// instead of the full argument (e.g., "-fsanitize=fuzzer")
SanitizerSet KindSet;
KindSet.Mask = KindsToDiagnose;
D.Diag(IsExplicitDevice
? diag::err_drv_unsupported_option_part_for_target
: diag::warn_drv_unsupported_option_part_for_target)
<< toString(KindSet) << Arg->getAsString(Args)
<< TC.getTriple().str();
} else {
// For non-offload targets, use the shorter diagnostic format
D.Diag(diag::err_drv_unsupported_opt_for_target)
<< Desc << TC.getTriple().str();
<< describeSanitizeArg(Arg, KindsToDiagnose)
<< TC.getTriple().str();
}

DiagnosedKinds |= KindsToDiagnose;
}
Add &= Supported;

Add &= BoundArchSupported;

// Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups
// so we don't error out if -fno-rtti and -fsanitize=undefined were
Expand Down Expand Up @@ -599,7 +673,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
options::OPT_fno_wrapv_pointer, S))
Add &= ~SanitizerKind::PointerOverflow;
}
Add &= Supported;
Add &= BoundArchSupported;

if (Add & SanitizerKind::Fuzzer)
Add |= SanitizerKind::FuzzerNoLink;
Expand Down Expand Up @@ -714,7 +788,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
// c++abi-specific parts of UBSan runtime, and they are not provided by the
// toolchain. We don't have a good way to check the latter, so we just
// check if the toolchan supports vptr.
if (~Supported & SanitizerKind::Vptr) {
if (~BoundArchSupported & SanitizerKind::Vptr) {
SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt;
// The runtime library supports the Microsoft C++ ABI, but only well enough
// for CFI. FIXME: Remove this once we support vptr on Windows.
Expand Down
13 changes: 9 additions & 4 deletions clang/lib/Driver/ToolChain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,8 +516,15 @@ ToolChain::getMultilibFlags(const llvm::opt::ArgList &Args) const {
}

SanitizerArgs
ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs) const {
SanitizerArgs SanArgs(*this, JobArgs, !SanitizerArgsChecked);
ToolChain::getSanitizerArgs(const llvm::opt::ArgList &JobArgs,
StringRef BoundArch,
Action::OffloadKind DeviceOffloadKind) const {
SanitizerArgs SanArgs(*this, JobArgs,
/*DiagnoseErrors=*/!SanitizerArgsChecked,
/*DiagnoseBoundArchErrors=*/
BoundArchSanitizerArgsChecked.insert(BoundArch).second,
BoundArch, DeviceOffloadKind);

SanitizerArgsChecked = true;
return SanArgs;
}
Expand Down Expand Up @@ -1807,8 +1814,6 @@ ToolChain::getSupportedSanitizers(StringRef BoundArch,
Res |= SanitizerKind::MemTag;
if (getTriple().isBPF())
Res |= SanitizerKind::KernelAddress;
if (getTriple().isAMDGPU())
Res |= SanitizerKind::Address;
return Res;
}

Expand Down
Loading