[Frontend] Diagnose rather than exit/assert on experimental features

Diagnose rather than exit when using experimental features that cannot
be enabled in production. Also diagnose if using a compiler without
`SwiftCompilerSources` when enabling embedded.

This is especially important for long-running services like sourcekitd,
which shouldn't exit just because an invalid argument was passed.

Resolves rdar://119724074.
This commit is contained in:
Ben Barham
2024-01-02 12:41:59 -08:00
parent 9019d07fd7
commit a6c8bf3818
2 changed files with 18 additions and 7 deletions

View File

@@ -563,6 +563,12 @@ ERROR(objc_with_embedded,none,
"Objective-C interoperability cannot be enabled with embedded Swift.", ()) "Objective-C interoperability cannot be enabled with embedded Swift.", ())
ERROR(no_allocations_without_embedded,none, ERROR(no_allocations_without_embedded,none,
"-no-allocations is only applicable with embedded Swift.", ()) "-no-allocations is only applicable with embedded Swift.", ())
ERROR(no_swift_sources_with_embedded,none,
"embedded swift cannot be enabled in a compiler built without Swift sources", ())
ERROR(experimental_not_supported_in_production,none,
"experimental feature '%0' cannot be enabled in production compiler",
(StringRef))
#define UNDEFINE_DIAGNOSTIC_MACROS #define UNDEFINE_DIAGNOSTIC_MACROS
#include "DefineDiagnosticMacros.h" #include "DefineDiagnosticMacros.h"

View File

@@ -845,13 +845,15 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
if (auto feature = getExperimentalFeature(value)) { if (auto feature = getExperimentalFeature(value)) {
#ifdef NDEBUG #ifdef NDEBUG
if (!isFeatureAvailableInProduction(*feature)) { if (!isFeatureAvailableInProduction(*feature)) {
llvm::errs() << "error: experimental feature '" << A->getValue() Diags.diagnose(SourceLoc(), diag::experimental_not_supported_in_production,
<< "' cannot be enabled in a production compiler\n"; A->getValue());
exit(1); HadError = true;
} else {
Opts.Features.insert(*feature);
} }
#endif #else
Opts.Features.insert(*feature); Opts.Features.insert(*feature);
#endif
} }
// Hack: In order to support using availability macros in SPM packages, we // Hack: In order to support using availability macros in SPM packages, we
@@ -1368,12 +1370,15 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.BypassResilienceChecks |= Args.hasArg(OPT_bypass_resilience); Opts.BypassResilienceChecks |= Args.hasArg(OPT_bypass_resilience);
if (Opts.hasFeature(Feature::Embedded)) { if (Opts.hasFeature(Feature::Embedded)) {
assert(swiftModulesInitialized() && "no SwiftCompilerSources");
Opts.UnavailableDeclOptimizationMode = UnavailableDeclOptimization::Complete; Opts.UnavailableDeclOptimizationMode = UnavailableDeclOptimization::Complete;
Opts.DisableImplicitStringProcessingModuleImport = true; Opts.DisableImplicitStringProcessingModuleImport = true;
Opts.DisableImplicitConcurrencyModuleImport = true; Opts.DisableImplicitConcurrencyModuleImport = true;
if (!swiftModulesInitialized()) {
Diags.diagnose(SourceLoc(), diag::no_swift_sources_with_embedded);
HadError = true;
}
if (FrontendOpts.EnableLibraryEvolution) { if (FrontendOpts.EnableLibraryEvolution) {
Diags.diagnose(SourceLoc(), diag::evolution_with_embedded); Diags.diagnose(SourceLoc(), diag::evolution_with_embedded);
HadError = true; HadError = true;