Skip to content

Commit 4c29858

Browse files
committed
Propagate response files correctly to the new driver.
If a response file is being passed to the legacy driver because it is too large to fit on the system's command line, then it should also be passed when spawning the new driver. Currently, however, the legacy driver attempts to pass the *expanded* arguments to the new driver, which can cause the invocation to fail, requiring the new driver to be disabled in order to compile. This change passes the original arguments into `run_driver` as well as the expanded ones, so that the branch that spawns the new driver can use the original arguments instead.
1 parent dc0ab28 commit 4c29858

File tree

4 files changed

+36
-4
lines changed

4 files changed

+36
-4
lines changed

lib/DriverTool/driver.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ static bool appendSwiftDriverName(SmallString<256> &buffer) {
184184
}
185185

186186
static int run_driver(StringRef ExecName,
187-
const ArrayRef<const char *> argv) {
187+
const ArrayRef<const char *> argv,
188+
const ArrayRef<const char *> originalArgv) {
188189
// This is done here and not done in FrontendTool.cpp, because
189190
// FrontendTool.cpp is linked to tools, which don't use swift modules.
190191
initializeSwiftModules();
@@ -244,7 +245,8 @@ static int run_driver(StringRef ExecName,
244245
subCommandArgs.push_back(NewDriverPath.c_str());
245246

246247
// Push on the source program arguments
247-
subCommandArgs.insert(subCommandArgs.end(), argv.begin() + 1, argv.end());
248+
subCommandArgs.insert(subCommandArgs.end(),
249+
originalArgv.begin() + 1, originalArgv.end());
248250

249251
// Execute the subcommand.
250252
subCommandArgs.push_back(nullptr);
@@ -393,12 +395,13 @@ int swift::mainEntry(int argc_, const char **argv_) {
393395
return 2;
394396
}
395397

398+
ArrayRef<const char *> originalArgv(argv_, &argv_[argc_]);
396399
if (isRepl) {
397400
// Preserve argv for the stack trace.
398401
SmallVector<const char *, 256> replArgs(argv.begin(), argv.end());
399402
replArgs.erase(&replArgs[1]);
400-
return run_driver(ExecName, replArgs);
403+
return run_driver(ExecName, replArgs, originalArgv);
401404
} else {
402-
return run_driver(ExecName, argv);
405+
return run_driver(ExecName, argv, originalArgv);
403406
}
404407
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env sh
2+
3+
for arg in "$@" ; do
4+
echo "$arg"
5+
done
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Verify that when the legacy driver (swift-frontend executable invoked as
2+
// swiftc) spawns the new driver, it passes the original arguments (i.e.,
3+
// preserving response files) instead of trying to spawn the process with the
4+
// expansion, which may exceed `ARG_MAX`.
5+
6+
// REQUIRES: shell
7+
// RUN: %{python} -c 'for i in range(500001): print("-DTEST5_" + str(i))' > %t.resp
8+
// RUN: cp %S/Inputs/print-args.sh %swift_obj_root/bin/legacy-driver-propagates-response-file.sh
9+
// RUN: env SWIFT_USE_NEW_DRIVER=legacy-driver-propagates-response-file.sh %swiftc_driver_plain %s @%t.resp | %FileCheck %s
10+
// RUN: rm %swift_obj_root/bin/legacy-driver-propagates-response-file.sh
11+
12+
// CHECK: -Xfrontend
13+
// CHECK-NEXT: -new-driver-path
14+
// CHECK-NEXT: -Xfrontend
15+
// CHECK-NEXT: legacy-driver-propagates-response-file.sh
16+
// CHECK: @{{.*}}.resp
17+
// CHECK-NOT: -DTEST5_{{.*}}
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Make a local copy of the environment.
2+
config.environment = dict(config.environment)
3+
4+
# Remove the settings that force tests to use the old driver so that tests
5+
# in this directory can set `SWIFT_USE_NEW_DRIVER` to test those code paths.
6+
del config.environment['SWIFT_USE_OLD_DRIVER']
7+
del config.environment['SWIFT_AVOID_WARNING_USING_OLD_DRIVER']

0 commit comments

Comments
 (0)