Skip to content

Commit 9b67988

Browse files
authored
[clang][darwin] Fix assertion failure when reporting fatal errors when inferring OS versions (#143817)
1 parent 2e5fb77 commit 9b67988

File tree

3 files changed

+68
-15
lines changed

3 files changed

+68
-15
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ def err_drv_cannot_open_randomize_layout_seed_file : Error<
206206
"cannot read randomize layout seed file '%0'">;
207207
def err_drv_invalid_version_number : Error<
208208
"invalid version number in '%0'">;
209+
def err_drv_invalid_version_number_inferred
210+
: Error<"invalid version number '%0' inferred from '%1'">;
209211
def err_drv_missing_version_number : Error<"missing version number in '%0'">;
210212
def err_drv_kcfi_arity_unsupported_target : Error<
211213
"target '%0' is unsupported by -fsanitize-kcfi-arity">;

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,16 +1793,23 @@ struct DarwinPlatform {
17931793
case TargetArg:
17941794
case MTargetOSArg:
17951795
case OSVersionArg:
1796-
case InferredFromSDK:
1797-
case InferredFromArch:
17981796
assert(Arg && "OS version argument not yet inferred");
17991797
return Arg->getAsString(Args);
18001798
case DeploymentTargetEnv:
18011799
return (llvm::Twine(EnvVarName) + "=" + OSVersionStr).str();
1800+
case InferredFromSDK:
1801+
case InferredFromArch:
1802+
llvm_unreachable("Cannot print arguments for inferred OS version");
18021803
}
18031804
llvm_unreachable("Unsupported Darwin Source Kind");
18041805
}
18051806

1807+
// Returns the inferred source of how the OS version was resolved.
1808+
std::string getInferredSource() {
1809+
assert(!isExplicitlySpecified() && "OS version was not inferred");
1810+
return InferredSource.str();
1811+
}
1812+
18061813
void setEnvironment(llvm::Triple::EnvironmentType EnvType,
18071814
const VersionTuple &OSVersion,
18081815
const std::optional<DarwinSDKInfo> &SDKInfo) {
@@ -1876,19 +1883,24 @@ struct DarwinPlatform {
18761883
Result.EnvVarName = EnvVarName;
18771884
return Result;
18781885
}
1879-
static DarwinPlatform createFromSDK(DarwinPlatformKind Platform,
1886+
static DarwinPlatform createFromSDK(StringRef SDKRoot,
1887+
DarwinPlatformKind Platform,
18801888
StringRef Value,
18811889
bool IsSimulator = false) {
18821890
DarwinPlatform Result(InferredFromSDK, Platform,
18831891
getVersionFromString(Value));
18841892
if (IsSimulator)
18851893
Result.Environment = DarwinEnvironmentKind::Simulator;
18861894
Result.InferSimulatorFromArch = false;
1895+
Result.InferredSource = SDKRoot;
18871896
return Result;
18881897
}
1889-
static DarwinPlatform createFromArch(llvm::Triple::OSType OS,
1898+
static DarwinPlatform createFromArch(StringRef Arch, llvm::Triple::OSType OS,
18901899
VersionTuple Version) {
1891-
return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Version);
1900+
auto Result =
1901+
DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Version);
1902+
Result.InferredSource = Arch;
1903+
return Result;
18921904
}
18931905

18941906
/// Constructs an inferred SDKInfo value based on the version inferred from
@@ -1975,6 +1987,9 @@ struct DarwinPlatform {
19751987
bool InferSimulatorFromArch = true;
19761988
std::pair<Arg *, std::string> Arguments;
19771989
StringRef EnvVarName;
1990+
// If the DarwinPlatform information is derived from an inferred source, this
1991+
// captures what that source input was for error reporting.
1992+
StringRef InferredSource;
19781993
// When compiling for a zippered target, this value represents the target
19791994
// triple encoded in the target variant.
19801995
std::optional<llvm::Triple> TargetVariantTriple;
@@ -2143,26 +2158,27 @@ inferDeploymentTargetFromSDK(DerivedArgList &Args,
21432158
[&](StringRef SDK) -> std::optional<DarwinPlatform> {
21442159
if (SDK.starts_with("iPhoneOS") || SDK.starts_with("iPhoneSimulator"))
21452160
return DarwinPlatform::createFromSDK(
2146-
Darwin::IPhoneOS, Version,
2161+
isysroot, Darwin::IPhoneOS, Version,
21472162
/*IsSimulator=*/SDK.starts_with("iPhoneSimulator"));
21482163
else if (SDK.starts_with("MacOSX"))
2149-
return DarwinPlatform::createFromSDK(Darwin::MacOS,
2164+
return DarwinPlatform::createFromSDK(isysroot, Darwin::MacOS,
21502165
getSystemOrSDKMacOSVersion(Version));
21512166
else if (SDK.starts_with("WatchOS") || SDK.starts_with("WatchSimulator"))
21522167
return DarwinPlatform::createFromSDK(
2153-
Darwin::WatchOS, Version,
2168+
isysroot, Darwin::WatchOS, Version,
21542169
/*IsSimulator=*/SDK.starts_with("WatchSimulator"));
21552170
else if (SDK.starts_with("AppleTVOS") ||
21562171
SDK.starts_with("AppleTVSimulator"))
21572172
return DarwinPlatform::createFromSDK(
2158-
Darwin::TvOS, Version,
2173+
isysroot, Darwin::TvOS, Version,
21592174
/*IsSimulator=*/SDK.starts_with("AppleTVSimulator"));
21602175
else if (SDK.starts_with("XR"))
21612176
return DarwinPlatform::createFromSDK(
2162-
Darwin::XROS, Version,
2177+
isysroot, Darwin::XROS, Version,
21632178
/*IsSimulator=*/SDK.contains("Simulator"));
21642179
else if (SDK.starts_with("DriverKit"))
2165-
return DarwinPlatform::createFromSDK(Darwin::DriverKit, Version);
2180+
return DarwinPlatform::createFromSDK(isysroot, Darwin::DriverKit,
2181+
Version);
21662182
return std::nullopt;
21672183
};
21682184
if (auto Result = CreatePlatformFromSDKName(SDK))
@@ -2236,7 +2252,7 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
22362252
if (OSTy == llvm::Triple::UnknownOS)
22372253
return std::nullopt;
22382254
return DarwinPlatform::createFromArch(
2239-
OSTy, getInferredOSVersion(OSTy, Triple, TheDriver));
2255+
MachOArchName, OSTy, getInferredOSVersion(OSTy, Triple, TheDriver));
22402256
}
22412257

22422258
/// Returns the deployment target that's specified using the -target option.
@@ -2455,9 +2471,15 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
24552471
}
24562472

24572473
assert(PlatformAndVersion && "Unable to infer Darwin variant");
2458-
if (!PlatformAndVersion->isValidOSVersion())
2459-
getDriver().Diag(diag::err_drv_invalid_version_number)
2460-
<< PlatformAndVersion->getAsString(Args, Opts);
2474+
if (!PlatformAndVersion->isValidOSVersion()) {
2475+
if (PlatformAndVersion->isExplicitlySpecified())
2476+
getDriver().Diag(diag::err_drv_invalid_version_number)
2477+
<< PlatformAndVersion->getAsString(Args, Opts);
2478+
else
2479+
getDriver().Diag(diag::err_drv_invalid_version_number_inferred)
2480+
<< PlatformAndVersion->getOSVersion().getAsString()
2481+
<< PlatformAndVersion->getInferredSource();
2482+
}
24612483
// After the deployment OS version has been resolved, set it to the canonical
24622484
// version before further error detection and converting to a proper target
24632485
// triple.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/// This test validates that the various ways to assign an invalid deployment version are captured and detected.
2+
// REQUIRES: system-darwin && native
3+
4+
// RUN: rm -rf %t
5+
// RUN: split-file %s %t
6+
7+
// RUN: env SDKROOT=%t/iPhoneOS21.0.sdk not %clang -m64 -c -### %s 2>&1 \
8+
// RUN: | FileCheck %s --check-prefix=SDKROOT
9+
10+
// RUN: not %clang -isysroot %t/iPhoneOS21.0.sdk -m64 -c -### %s 2>&1 \
11+
// RUN: | FileCheck %s --check-prefix=SYSROOT
12+
13+
// RUN: not %clang -target arm64-apple-ios21 -c -### %s 2>&1 \
14+
// RUN: | FileCheck %s --check-prefix=TARGET
15+
16+
// RUN: not %clang -mtargetos=ios21 -arch arm64 -c -### %s 2>&1 \
17+
// RUN: | FileCheck %s --check-prefix=MTARGET
18+
19+
// RUN: env IPHONEOS_DEPLOYMENT_TARGET=21.0 not %clang -arch arm64 -c -### %s 2>&1 \
20+
// RUN: | FileCheck %s --check-prefix=DEPLOY_VAR
21+
22+
// SDKROOT: error: invalid version number '21.0' inferred from '{{.*}}.sdk'
23+
// SYSROOT: error: invalid version number '21.0' inferred from '{{.*}}.sdk'
24+
// TARGET: error: invalid version number in '-target arm64-apple-ios21'
25+
// MTARGET: error: invalid version number in '-mtargetos=ios21'
26+
// DEPLOY_VAR: error: invalid version number in 'IPHONEOS_DEPLOYMENT_TARGET=21.0'
27+
28+
//--- iPhoneOS21.0.sdk/SDKSettings.json
29+
{"Version":"21.0", "MaximumDeploymentTarget": "21.0.99"}

0 commit comments

Comments
 (0)