[libcxx] [test] Fix the _supportsVerify check on Windows by fixing quoting

The pipes.quote function quotes using single quotes, the same goes
for the newer shlex.quote (which is the preferred form in Python 3).
This isn't suitable for quoting in command lines on Windows (and the
documentation for shlex.quote even says it's only usable for Unix
shells).

In general, the python subprocess.list2cmdline function should do
proper quoting for the platform's current shell. However, it doesn't
quote the ';' char, which we pass within some arguments to run.py.
Therefore use the custom reimplementation from lit.TestRunner which
is amended to quote ';' too.

The fact that arguemnts were quoted with single quotes didn't matter
for command lines that were executed by either bash or the lit internal
shell, but if executing things directly using subprocess.call, as in
_supportsVerify, the quoted path to %{cxx} fails to be resolved by the
Windows shell.

This unlocks 114 tests that previously were skipped on Windows.

Differential Revision: https://reviews.llvm.org/D103310
This commit is contained in:
Martin Storsjö 2021-05-28 09:57:21 +00:00
parent 0be2657c2f
commit 41d7909368
2 changed files with 13 additions and 6 deletions

View File

@ -10,6 +10,7 @@ import copy
import os
import pkgutil
import pipes
import platform
import re
import shlex
import shutil
@ -21,6 +22,7 @@ import libcxx.util
import libcxx.test.features
import libcxx.test.newconfig
import libcxx.test.params
import lit
def loadSiteConfig(lit_config, config, param_name, env_name):
# We haven't loaded the site specific configuration (the user is
@ -490,17 +492,22 @@ class Configuration(object):
self.config.available_features.add('-fmodules')
self.cxx.useModules()
def quote(self, s):
if platform.system() == 'Windows':
return lit.TestRunner.quote_windows_command([s])
return pipes.quote(s)
def configure_substitutions(self):
sub = self.config.substitutions
sub.append(('%{cxx}', pipes.quote(self.cxx.path)))
sub.append(('%{cxx}', self.quote(self.cxx.path)))
flags = self.cxx.flags + (self.cxx.modules_flags if self.cxx.use_modules else [])
compile_flags = self.cxx.compile_flags + (self.cxx.warning_flags if self.cxx.use_warnings else [])
sub.append(('%{flags}', ' '.join(map(pipes.quote, flags))))
sub.append(('%{compile_flags}', ' '.join(map(pipes.quote, compile_flags))))
sub.append(('%{link_flags}', ' '.join(map(pipes.quote, self.cxx.link_flags))))
sub.append(('%{flags}', ' '.join(map(self.quote, flags))))
sub.append(('%{compile_flags}', ' '.join(map(self.quote, compile_flags))))
sub.append(('%{link_flags}', ' '.join(map(self.quote, self.cxx.link_flags))))
codesign_ident = self.get_lit_conf('llvm_codesign_identity', '')
env_vars = ' '.join('%s=%s' % (k, pipes.quote(v)) for (k, v) in self.exec_env.items())
env_vars = ' '.join('%s=%s' % (k, self.quote(v)) for (k, v) in self.exec_env.items())
exec_args = [
'--execdir %T',
'--codesign_identity "{}"'.format(codesign_ident),

View File

@ -209,7 +209,7 @@ def quote_windows_command(seq):
result.append(' ')
# This logic differs from upstream list2cmdline.
needquote = (" " in arg) or ("\t" in arg) or ("\"" in arg) or ("[" in arg) or not arg
needquote = (" " in arg) or ("\t" in arg) or ("\"" in arg) or ("[" in arg) or (";" in arg) or not arg
if needquote:
result.append('"')