[clang] [clang][darwin] Fix assertion failure when reporting fatal errors when inferring OS versions (PR #143817)
Cyndy Ishida via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 11 22:15:41 PDT 2025
https://github.com/cyndyishida updated https://github.com/llvm/llvm-project/pull/143817
>From 11b78ef3b9464aba1e54dcf9c18fceea359d16eb Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Wed, 11 Jun 2025 17:20:20 -0700
Subject: [PATCH] [clang][darwin] Fix assertion failure when reporting fatal
errors when inferring OS versions
---
.../clang/Basic/DiagnosticDriverKinds.td | 2 +
clang/lib/Driver/ToolChains/Darwin.cpp | 52 +++++++++++++------
.../Driver/darwin-invalid-version-range.c | 29 +++++++++++
3 files changed, 68 insertions(+), 15 deletions(-)
create mode 100644 clang/test/Driver/darwin-invalid-version-range.c
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 20fb47237c56f..29f6480ba935c 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -206,6 +206,8 @@ def err_drv_cannot_open_randomize_layout_seed_file : Error<
"cannot read randomize layout seed file '%0'">;
def err_drv_invalid_version_number : Error<
"invalid version number in '%0'">;
+def err_drv_invalid_version_number_inferred
+ : Error<"invalid version number '%0' inferred from '%1'">;
def err_drv_missing_version_number : Error<"missing version number in '%0'">;
def err_drv_kcfi_arity_unsupported_target : Error<
"target '%0' is unsupported by -fsanitize-kcfi-arity">;
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index e987ef78920e8..e5075cbcaf660 100644
--- a/clang/lib/Driver/ToolChains/Darwin.cpp
+++ b/clang/lib/Driver/ToolChains/Darwin.cpp
@@ -1793,16 +1793,23 @@ struct DarwinPlatform {
case TargetArg:
case MTargetOSArg:
case OSVersionArg:
- case InferredFromSDK:
- case InferredFromArch:
assert(Arg && "OS version argument not yet inferred");
return Arg->getAsString(Args);
case DeploymentTargetEnv:
return (llvm::Twine(EnvVarName) + "=" + OSVersionStr).str();
+ case InferredFromSDK:
+ case InferredFromArch:
+ llvm_unreachable("Cannot print arguments for inferred OS version");
}
llvm_unreachable("Unsupported Darwin Source Kind");
}
+ // Returns the inferred source of how the OS version was resolved.
+ std::string getInferredSource() {
+ assert(!isExplicitlySpecified() && "OS version was not inferred");
+ return InferredSource.str();
+ }
+
void setEnvironment(llvm::Triple::EnvironmentType EnvType,
const VersionTuple &OSVersion,
const std::optional<DarwinSDKInfo> &SDKInfo) {
@@ -1876,7 +1883,8 @@ struct DarwinPlatform {
Result.EnvVarName = EnvVarName;
return Result;
}
- static DarwinPlatform createFromSDK(DarwinPlatformKind Platform,
+ static DarwinPlatform createFromSDK(StringRef SDKRoot,
+ DarwinPlatformKind Platform,
StringRef Value,
bool IsSimulator = false) {
DarwinPlatform Result(InferredFromSDK, Platform,
@@ -1884,11 +1892,15 @@ struct DarwinPlatform {
if (IsSimulator)
Result.Environment = DarwinEnvironmentKind::Simulator;
Result.InferSimulatorFromArch = false;
+ Result.InferredSource = SDKRoot;
return Result;
}
- static DarwinPlatform createFromArch(llvm::Triple::OSType OS,
+ static DarwinPlatform createFromArch(StringRef Arch, llvm::Triple::OSType OS,
VersionTuple Version) {
- return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Version);
+ auto Result =
+ DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Version);
+ Result.InferredSource = Arch;
+ return Result;
}
/// Constructs an inferred SDKInfo value based on the version inferred from
@@ -1975,6 +1987,9 @@ struct DarwinPlatform {
bool InferSimulatorFromArch = true;
std::pair<Arg *, std::string> Arguments;
StringRef EnvVarName;
+ // If the DarwinPlatform information is derived from an inferred source, this
+ // captures what that source input was for error reporting.
+ StringRef InferredSource;
// When compiling for a zippered target, this value represents the target
// triple encoded in the target variant.
std::optional<llvm::Triple> TargetVariantTriple;
@@ -2143,26 +2158,27 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args,
[&](StringRef SDK) -> std::optional<DarwinPlatform> {
if (SDK.starts_with("iPhoneOS") || SDK.starts_with("iPhoneSimulator"))
return DarwinPlatform::createFromSDK(
- Darwin::IPhoneOS, Version,
+ isysroot, Darwin::IPhoneOS, Version,
/*IsSimulator=*/SDK.starts_with("iPhoneSimulator"));
else if (SDK.starts_with("MacOSX"))
- return DarwinPlatform::createFromSDK(Darwin::MacOS,
+ return DarwinPlatform::createFromSDK(isysroot, Darwin::MacOS,
getSystemOrSDKMacOSVersion(Version));
else if (SDK.starts_with("WatchOS") || SDK.starts_with("WatchSimulator"))
return DarwinPlatform::createFromSDK(
- Darwin::WatchOS, Version,
+ isysroot, Darwin::WatchOS, Version,
/*IsSimulator=*/SDK.starts_with("WatchSimulator"));
else if (SDK.starts_with("AppleTVOS") ||
SDK.starts_with("AppleTVSimulator"))
return DarwinPlatform::createFromSDK(
- Darwin::TvOS, Version,
+ isysroot, Darwin::TvOS, Version,
/*IsSimulator=*/SDK.starts_with("AppleTVSimulator"));
else if (SDK.starts_with("XR"))
return DarwinPlatform::createFromSDK(
- Darwin::XROS, Version,
+ isysroot, Darwin::XROS, Version,
/*IsSimulator=*/SDK.contains("Simulator"));
else if (SDK.starts_with("DriverKit"))
- return DarwinPlatform::createFromSDK(Darwin::DriverKit, Version);
+ return DarwinPlatform::createFromSDK(isysroot, Darwin::DriverKit,
+ Version);
return std::nullopt;
};
if (auto Result = CreatePlatformFromSDKName(SDK))
@@ -2236,7 +2252,7 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
if (OSTy == llvm::Triple::UnknownOS)
return std::nullopt;
return DarwinPlatform::createFromArch(
- OSTy, getInferredOSVersion(OSTy, Triple, TheDriver));
+ MachOArchName, OSTy, getInferredOSVersion(OSTy, Triple, TheDriver));
}
/// Returns the deployment target that's specified using the -target option.
@@ -2455,9 +2471,15 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
}
assert(PlatformAndVersion && "Unable to infer Darwin variant");
- if (!PlatformAndVersion->isValidOSVersion())
- getDriver().Diag(diag::err_drv_invalid_version_number)
- << PlatformAndVersion->getAsString(Args, Opts);
+ if (!PlatformAndVersion->isValidOSVersion()) {
+ if (PlatformAndVersion->isExplicitlySpecified())
+ getDriver().Diag(diag::err_drv_invalid_version_number)
+ << PlatformAndVersion->getAsString(Args, Opts);
+ else
+ getDriver().Diag(diag::err_drv_invalid_version_number_inferred)
+ << PlatformAndVersion->getOSVersion().getAsString()
+ << PlatformAndVersion->getInferredSource();
+ }
// After the deployment OS version has been resolved, set it to the canonical
// version before further error detection and converting to a proper target
// triple.
diff --git a/clang/test/Driver/darwin-invalid-version-range.c b/clang/test/Driver/darwin-invalid-version-range.c
new file mode 100644
index 0000000000000..84603aec1d2f5
--- /dev/null
+++ b/clang/test/Driver/darwin-invalid-version-range.c
@@ -0,0 +1,29 @@
+/// This test validates that the various ways to assign an invalid deployment version are captured and detected.
+// REQUIRES: system-darwin && native
+
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+
+// RUN: env SDKROOT=%t/iPhoneOS21.0.sdk not %clang -m64 -c -### %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=SDKROOT
+
+// RUN: not %clang -isysroot %t/iPhoneOS21.0.sdk -m64 -c -### %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=SYSROOT
+
+// RUN: not %clang -target arm64-apple-ios21 -c -### %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=TARGET
+
+// RUN: not %clang -mtargetos=ios21 -arch arm64 -c -### %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=MTARGET
+
+// RUN: env IPHONEOS_DEPLOYMENT_TARGET=21.0 not %clang -arch arm64 -c -### %s 2>&1 \
+// RUN: | FileCheck %s --check-prefix=DEPLOY_VAR
+
+// SDKROOT: error: invalid version number '21.0' inferred from '{{.*}}.sdk'
+// SYSROOT: error: invalid version number '21.0' inferred from '{{.*}}.sdk'
+// TARGET: error: invalid version number in '-target arm64-apple-ios21'
+// MTARGET: error: invalid version number in '-mtargetos=ios21'
+// DEPLOY_VAR: error: invalid version number in 'IPHONEOS_DEPLOYMENT_TARGET=21.0'
+
+//--- iPhoneOS21.0.sdk/SDKSettings.json
+{"Version":"21.0", "MaximumDeploymentTarget": "21.0.99"}
More information about the cfe-commits
mailing list