Adjust libc++ test infastructure to fully support modules

This patch overhalls the libc++ test format/configuration in order to fully support modules. By "fully support" I mean get almost all of the tests passing. The main hurdle for doing this is handling tests that `#define _LIBCPP_FOO` macros to test a different configuration. This patch deals with these tests in the following ways:

1. For tests that define single `_LIBCPP_ABI_FOO` macros have been annotated with `// MODULES_DEFINES: _LIBCPP_ABI_FOO`. This allows the test suite to define the macro on the command line so it uses a different set of modules.
2. Tests for libc++'s debug mode (which define custom `_LIBCPP_ASSERT`) are automatically detected by the test suite and are compiled and run with modules disabled.

This patch also cleans up how the `CXXCompiler` helper class handles enabling/disabling language features.

NOTE: This patch uses `LIT` features which were only committed to LLVM today. If this patch breaks running the libc++ tests you probably need to update LLVM.

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@288728 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2016-12-05 23:16:07 +00:00
parent c6d8e8a9cc
commit bca6de0e4e
37 changed files with 207 additions and 140 deletions

View File

@@ -389,7 +389,7 @@ module std [system] {
} }
module strstream { module strstream {
header "strstream" header "strstream"
requires !cplusplus11 export *
} }
module system_error { module system_error {
header "system_error" header "system_error"

View File

@@ -12,6 +12,7 @@
// Test that including <atomic> fails to compile when _LIBCPP_HAS_NO_THREADS // Test that including <atomic> fails to compile when _LIBCPP_HAS_NO_THREADS
// is defined. // is defined.
// MODULES_DEFINES: _LIBCPP_HAS_NO_THREADS
#ifndef _LIBCPP_HAS_NO_THREADS #ifndef _LIBCPP_HAS_NO_THREADS
#define _LIBCPP_HAS_NO_THREADS #define _LIBCPP_HAS_NO_THREADS
#endif #endif

View File

@@ -7,6 +7,7 @@
# #
#===----------------------------------------------------------------------===## #===----------------------------------------------------------------------===##
import platform
import os import os
import lit.util import lit.util
import libcxx.util import libcxx.util
@@ -19,16 +20,47 @@ class CXXCompiler(object):
CM_Link = 3 CM_Link = 3
def __init__(self, path, flags=None, compile_flags=None, link_flags=None, def __init__(self, path, flags=None, compile_flags=None, link_flags=None,
use_ccache=False): warning_flags=None, modules_flags=None, use_modules=False,
use_ccache=False, use_warnings=False, compile_env=None,
cxx_type=None, cxx_version=None):
self.path = path self.path = path
self.flags = list(flags or []) self.flags = list(flags or [])
self.compile_flags = list(compile_flags or []) self.compile_flags = list(compile_flags or [])
self.warning_flags = [] self.warning_flags = list(warning_flags or [])
self.link_flags = list(link_flags or []) self.link_flags = list(link_flags or [])
self.modules_flags = list(modules_flags or [])
self.use_modules = use_modules
assert not use_modules or modules_flags is not None
self.use_ccache = use_ccache self.use_ccache = use_ccache
self.type = None self.use_warnings = use_warnings
self.version = None if compile_env is not None:
self._initTypeAndVersion() self.compile_env = dict(compile_env)
else:
self.compile_env = None
self.type = cxx_type
self.version = cxx_version
if self.type is None or self.version is None:
self._initTypeAndVersion()
def copy(self):
new_cxx = CXXCompiler(
self.path, flags=self.flags, compile_flags=self.compile_flags,
link_flags=self.link_flags, warning_flags=self.warning_flags,
modules_flags=self.modules_flags, use_modules=self.use_modules,
use_ccache=self.use_ccache, use_warnings=self.use_warnings,
compile_env=self.compile_env, cxx_type=self.type,
cxx_version=self.version)
return new_cxx
def useModules(self, value=True):
self.use_modules = value
assert not self.use_modules or self.modules_flags is not None
def useCCache(self, value=True):
self.use_ccache = value
def useWarnings(self, value=True):
self.use_warnings = value
def _initTypeAndVersion(self): def _initTypeAndVersion(self):
# Get compiler type and version # Get compiler type and version
@@ -54,10 +86,9 @@ class CXXCompiler(object):
self.version = (major_ver, minor_ver, patchlevel) self.version = (major_ver, minor_ver, patchlevel)
def _basicCmd(self, source_files, out, mode=CM_Default, flags=[], def _basicCmd(self, source_files, out, mode=CM_Default, flags=[],
input_is_cxx=False, input_is_cxx=False):
enable_warnings=True, disable_ccache=False):
cmd = [] cmd = []
if self.use_ccache and not disable_ccache \ if self.use_ccache \
and not mode == self.CM_Link \ and not mode == self.CM_Link \
and not mode == self.CM_PreProcess: and not mode == self.CM_PreProcess:
cmd += ['ccache'] cmd += ['ccache']
@@ -77,68 +108,64 @@ class CXXCompiler(object):
elif mode == self.CM_Compile: elif mode == self.CM_Compile:
cmd += ['-c'] cmd += ['-c']
cmd += self.flags cmd += self.flags
if self.use_modules:
cmd += self.modules_flags
if mode != self.CM_Link: if mode != self.CM_Link:
cmd += self.compile_flags cmd += self.compile_flags
if enable_warnings: if self.use_warnings:
cmd += self.warning_flags cmd += self.warning_flags
if mode != self.CM_PreProcess and mode != self.CM_Compile: if mode != self.CM_PreProcess and mode != self.CM_Compile:
cmd += self.link_flags cmd += self.link_flags
cmd += flags cmd += flags
return cmd return cmd
def _getWarningFlags(self, enable_warnings=True): def _getWarningFlags(self):
return self.warning_flags if enable_warnings else [] return self.warning_flags if self.use_warnings else []
def preprocessCmd(self, source_files, out=None, flags=[], def preprocessCmd(self, source_files, out=None, flags=[]):
enable_warnings=True):
return self._basicCmd(source_files, out, flags=flags, return self._basicCmd(source_files, out, flags=flags,
mode=self.CM_PreProcess, mode=self.CM_PreProcess,
enable_warnings=enable_warnings,
input_is_cxx=True) input_is_cxx=True)
def compileCmd(self, source_files, out=None, flags=[], def compileCmd(self, source_files, out=None, flags=[]):
disable_ccache=False, enable_warnings=True):
return self._basicCmd(source_files, out, flags=flags, return self._basicCmd(source_files, out, flags=flags,
mode=self.CM_Compile, mode=self.CM_Compile,
input_is_cxx=True, input_is_cxx=True) + ['-c']
enable_warnings=enable_warnings,
disable_ccache=disable_ccache) + ['-c']
def linkCmd(self, source_files, out=None, flags=[]): def linkCmd(self, source_files, out=None, flags=[]):
return self._basicCmd(source_files, out, mode=self.CM_Link)
def compileLinkCmd(self, source_files, out=None, flags=[],
enable_warnings=True):
return self._basicCmd(source_files, out, flags=flags, return self._basicCmd(source_files, out, flags=flags,
enable_warnings=enable_warnings) mode=self.CM_Link)
def preprocess(self, source_files, out=None, flags=[], env=None, cwd=None): def compileLinkCmd(self, source_files, out=None, flags=[]):
return self._basicCmd(source_files, out, flags=flags)
def preprocess(self, source_files, out=None, flags=[], cwd=None):
cmd = self.preprocessCmd(source_files, out, flags) cmd = self.preprocessCmd(source_files, out, flags)
out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd) out, err, rc = lit.util.executeCommand(cmd, env=self.compile_env,
cwd=cwd)
return cmd, out, err, rc return cmd, out, err, rc
def compile(self, source_files, out=None, flags=[], env=None, cwd=None, def compile(self, source_files, out=None, flags=[], cwd=None):
disable_ccache=False, enable_warnings=True): cmd = self.compileCmd(source_files, out, flags)
cmd = self.compileCmd(source_files, out, flags, out, err, rc = lit.util.executeCommand(cmd, env=self.compile_env,
disable_ccache=disable_ccache, cwd=cwd)
enable_warnings=enable_warnings)
out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd)
return cmd, out, err, rc return cmd, out, err, rc
def link(self, source_files, out=None, flags=[], env=None, cwd=None): def link(self, source_files, out=None, flags=[], cwd=None):
cmd = self.linkCmd(source_files, out, flags) cmd = self.linkCmd(source_files, out, flags)
out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd) out, err, rc = lit.util.executeCommand(cmd, env=self.compile_env,
cwd=cwd)
return cmd, out, err, rc return cmd, out, err, rc
def compileLink(self, source_files, out=None, flags=[], env=None, def compileLink(self, source_files, out=None, flags=[],
cwd=None): cwd=None):
cmd = self.compileLinkCmd(source_files, out, flags) cmd = self.compileLinkCmd(source_files, out, flags)
out, err, rc = lit.util.executeCommand(cmd, env=env, cwd=cwd) out, err, rc = lit.util.executeCommand(cmd, env=self.compile_env,
cwd=cwd)
return cmd, out, err, rc return cmd, out, err, rc
def compileLinkTwoSteps(self, source_file, out=None, object_file=None, def compileLinkTwoSteps(self, source_file, out=None, object_file=None,
flags=[], env=None, cwd=None, flags=[], cwd=None):
disable_ccache=False):
if not isinstance(source_file, str): if not isinstance(source_file, str):
raise TypeError('This function only accepts a single input file') raise TypeError('This function only accepts a single input file')
if object_file is None: if object_file is None:
@@ -149,22 +176,20 @@ class CXXCompiler(object):
with_fn = lambda: libcxx.util.nullContext(object_file) with_fn = lambda: libcxx.util.nullContext(object_file)
with with_fn() as object_file: with with_fn() as object_file:
cc_cmd, cc_stdout, cc_stderr, rc = self.compile( cc_cmd, cc_stdout, cc_stderr, rc = self.compile(
source_file, object_file, flags=flags, env=env, cwd=cwd, source_file, object_file, flags=flags, cwd=cwd)
disable_ccache=disable_ccache)
if rc != 0: if rc != 0:
return cc_cmd, cc_stdout, cc_stderr, rc return cc_cmd, cc_stdout, cc_stderr, rc
link_cmd, link_stdout, link_stderr, rc = self.link( link_cmd, link_stdout, link_stderr, rc = self.link(
object_file, out=out, flags=flags, env=env, cwd=cwd) object_file, out=out, flags=flags, cwd=cwd)
return (cc_cmd + ['&&'] + link_cmd, cc_stdout + link_stdout, return (cc_cmd + ['&&'] + link_cmd, cc_stdout + link_stdout,
cc_stderr + link_stderr, rc) cc_stderr + link_stderr, rc)
def dumpMacros(self, source_files=None, flags=[], env=None, cwd=None): def dumpMacros(self, source_files=None, flags=[], cwd=None):
if source_files is None: if source_files is None:
source_files = os.devnull source_files = os.devnull
flags = ['-dM'] + flags flags = ['-dM'] + flags
cmd, out, err, rc = self.preprocess(source_files, flags=flags, env=env, cmd, out, err, rc = self.preprocess(source_files, flags=flags, cwd=cwd)
cwd=cwd)
if rc != 0: if rc != 0:
return None return None
parsed_macros = {} parsed_macros = {}
@@ -215,11 +240,11 @@ class CXXCompiler(object):
else: else:
return False return False
def addWarningFlagIfSupported(self, flag): def hasWarningFlag(self, flag):
""" """
addWarningFlagIfSupported - Add a warning flag if the compiler hasWarningFlag - Test if the compiler supports a given warning flag.
supports it. Unlike addCompileFlagIfSupported, this function detects Unlike addCompileFlagIfSupported, this function detects when
when "-Wno-<warning>" flags are unsupported. If flag is a "-Wno-<warning>" flags are unsupported. If flag is a
"-Wno-<warning>" GCC will not emit an unknown option diagnostic unless "-Wno-<warning>" GCC will not emit an unknown option diagnostic unless
another error is triggered during compilation. another error is triggered during compilation.
""" """
@@ -230,7 +255,10 @@ class CXXCompiler(object):
return True return True
return False return False
flags = ['-Werror', flag] flags = ['-Werror', flag]
cmd = self.compileCmd('-', os.devnull, flags, enable_warnings=False) old_use_warnings = self.use_warnings
self.useWarnings(False)
cmd = self.compileCmd('-', os.devnull, flags)
self.useWarnings(True)
# Remove '-v' because it will cause the command line invocation # Remove '-v' because it will cause the command line invocation
# to be printed as part of the error output. # to be printed as part of the error output.
# TODO(EricWF): Are there other flags we need to worry about? # TODO(EricWF): Are there other flags we need to worry about?
@@ -240,5 +268,10 @@ class CXXCompiler(object):
assert rc != 0 assert rc != 0
if flag in err: if flag in err:
return False return False
self.warning_flags += [flag]
return True return True
def addWarningFlagIfSupported(self, flag):
if self.hasWarningFlag(flag):
self.warning_flags += [flag]
return True
return False

View File

@@ -12,6 +12,7 @@
// deque() // deque()
// deque::iterator() // deque::iterator()
// MODULES_DEFINES: _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
#define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE #define _LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE
#include <deque> #include <deque>
#include <cassert> #include <cassert>

View File

@@ -19,6 +19,7 @@
// When exceptions are disabled, all iterators should get this "fast path" // When exceptions are disabled, all iterators should get this "fast path"
// //
// MODULES_DEFINES: _LIBCPP_NO_EXCEPTIONS
#define _LIBCPP_NO_EXCEPTIONS #define _LIBCPP_NO_EXCEPTIONS
#include <iterator> #include <iterator>

View File

@@ -65,8 +65,6 @@ class Configuration(object):
self.cxx_library_root = None self.cxx_library_root = None
self.cxx_runtime_root = None self.cxx_runtime_root = None
self.abi_library_root = None self.abi_library_root = None
self.enable_modules = False
self.modules_flags = None
self.env = {} self.env = {}
self.use_target = False self.use_target = False
self.use_system_cxx_lib = False self.use_system_cxx_lib = False
@@ -128,6 +126,9 @@ class Configuration(object):
# Print the final compile and link flags. # Print the final compile and link flags.
self.lit_config.note('Using compiler: %s' % self.cxx.path) self.lit_config.note('Using compiler: %s' % self.cxx.path)
self.lit_config.note('Using flags: %s' % self.cxx.flags) self.lit_config.note('Using flags: %s' % self.cxx.flags)
if self.cxx.use_modules:
self.lit_config.note('Using modules flags: %s' %
self.cxx.modules_flags)
self.lit_config.note('Using compile flags: %s' self.lit_config.note('Using compile flags: %s'
% self.cxx.compile_flags) % self.cxx.compile_flags)
if len(self.cxx.warning_flags): if len(self.cxx.warning_flags):
@@ -735,8 +736,8 @@ class Configuration(object):
if platform.system() != 'Darwin': if platform.system() != 'Darwin':
modules_flags += ['-Xclang', '-fmodules-local-submodule-visibility'] modules_flags += ['-Xclang', '-fmodules-local-submodule-visibility']
supports_modules = self.cxx.hasCompileFlag(modules_flags) supports_modules = self.cxx.hasCompileFlag(modules_flags)
self.enable_modules = self.get_lit_bool('enable_modules', False) enable_modules = self.get_lit_bool('enable_modules', False)
if self.enable_modules and not supports_modules: if enable_modules and not supports_modules:
self.lit_config.fatal( self.lit_config.fatal(
'-fmodules is enabled but not supported by the compiler') '-fmodules is enabled but not supported by the compiler')
if not supports_modules: if not supports_modules:
@@ -748,11 +749,11 @@ class Configuration(object):
if os.path.isdir(module_cache): if os.path.isdir(module_cache):
shutil.rmtree(module_cache) shutil.rmtree(module_cache)
os.makedirs(module_cache) os.makedirs(module_cache)
self.modules_flags = modules_flags + \ self.cxx.modules_flags = modules_flags + \
['-fmodules-cache-path=' + module_cache] ['-fmodules-cache-path=' + module_cache]
if self.enable_modules: if enable_modules:
self.config.available_features.add('-fmodules') self.config.available_features.add('-fmodules')
self.cxx.compile_flags += self.modules_flags self.cxx.useModules()
def configure_substitutions(self): def configure_substitutions(self):
sub = self.config.substitutions sub = self.config.substitutions
@@ -777,10 +778,10 @@ class Configuration(object):
build_str = self.cxx.path + ' -o %t.exe %s ' + all_flags build_str = self.cxx.path + ' -o %t.exe %s ' + all_flags
sub.append(('%compile', compile_str)) sub.append(('%compile', compile_str))
sub.append(('%link', link_str)) sub.append(('%link', link_str))
if self.enable_modules: if self.cxx.use_modules:
sub.append(('%build_module', build_str)) sub.append(('%build_module', build_str))
elif self.modules_flags is not None: elif self.cxx.modules_flags is not None:
modules_str = ' '.join(self.modules_flags) + ' ' modules_str = ' '.join(self.cxx.modules_flags) + ' '
sub.append(('%build_module', build_str + ' ' + modules_str)) sub.append(('%build_module', build_str + ' ' + modules_str))
sub.append(('%build', build_str)) sub.append(('%build', build_str))
# Configure exec prefix substitutions. # Configure exec prefix substitutions.

View File

@@ -10,11 +10,15 @@
import errno import errno
import os import os
import time import time
import random
import lit.Test # pylint: disable=import-error import lit.Test # pylint: disable=import-error
import lit.TestRunner # pylint: disable=import-error import lit.TestRunner # pylint: disable=import-error
from lit.TestRunner import ParserKind, IntegratedTestKeywordParser \
# pylint: disable=import-error
import lit.util # pylint: disable=import-error import lit.util # pylint: disable=import-error
from libcxx.test.executor import LocalExecutor as LocalExecutor from libcxx.test.executor import LocalExecutor as LocalExecutor
import libcxx.util import libcxx.util
@@ -32,16 +36,32 @@ class LibcxxTestFormat(object):
def __init__(self, cxx, use_verify_for_fail, execute_external, def __init__(self, cxx, use_verify_for_fail, execute_external,
executor, exec_env): executor, exec_env):
self.cxx = cxx self.cxx = cxx.copy()
self.use_verify_for_fail = use_verify_for_fail self.use_verify_for_fail = use_verify_for_fail
self.execute_external = execute_external self.execute_external = execute_external
self.executor = executor self.executor = executor
self.exec_env = dict(exec_env) self.exec_env = dict(exec_env)
self.compile_env = dict(os.environ) self.cxx.compile_env = dict(os.environ)
# 'CCACHE_CPP2' prevents ccache from stripping comments while # 'CCACHE_CPP2' prevents ccache from stripping comments while
# preprocessing. This is required to prevent stripping of '-verify' # preprocessing. This is required to prevent stripping of '-verify'
# comments. # comments.
self.compile_env['CCACHE_CPP2'] = '1' self.cxx.compile_env['CCACHE_CPP2'] = '1'
@staticmethod
def _make_custom_parsers():
return [
IntegratedTestKeywordParser('FLAKY_TEST.', ParserKind.TAG,
initial_value=False),
IntegratedTestKeywordParser('MODULES_DEFINES:', ParserKind.LIST,
initial_value=[])
]
@staticmethod
def _get_parser(key, parsers):
for p in parsers:
if p.keyword == key:
return p
assert False and "parser not found"
# TODO: Move this into lit's FileBasedTest # TODO: Move this into lit's FileBasedTest
def getTestsInDirectory(self, testSuite, path_in_suite, def getTestsInDirectory(self, testSuite, path_in_suite,
@@ -71,6 +91,7 @@ class LibcxxTestFormat(object):
def _execute(self, test, lit_config): def _execute(self, test, lit_config):
name = test.path_in_suite[-1] name = test.path_in_suite[-1]
name_root, name_ext = os.path.splitext(name) name_root, name_ext = os.path.splitext(name)
is_libcxx_test = test.path_in_suite[0] == 'libcxx'
is_sh_test = name_root.endswith('.sh') is_sh_test = name_root.endswith('.sh')
is_pass_test = name.endswith('.pass.cpp') is_pass_test = name.endswith('.pass.cpp')
is_fail_test = name.endswith('.fail.cpp') is_fail_test = name.endswith('.fail.cpp')
@@ -80,8 +101,9 @@ class LibcxxTestFormat(object):
return (lit.Test.UNSUPPORTED, return (lit.Test.UNSUPPORTED,
"A lit.local.cfg marked this unsupported") "A lit.local.cfg marked this unsupported")
parsers = self._make_custom_parsers()
script = lit.TestRunner.parseIntegratedTestScript( script = lit.TestRunner.parseIntegratedTestScript(
test, require_script=is_sh_test) test, additional_parsers=parsers, require_script=is_sh_test)
# Check if a result for the test was returned. If so return that # Check if a result for the test was returned. If so return that
# result. # result.
if isinstance(script, lit.Test.Result): if isinstance(script, lit.Test.Result):
@@ -98,6 +120,25 @@ class LibcxxTestFormat(object):
tmpBase) tmpBase)
script = lit.TestRunner.applySubstitutions(script, substitutions) script = lit.TestRunner.applySubstitutions(script, substitutions)
test_cxx = self.cxx.copy()
if is_fail_test:
test_cxx.useCCache(False)
test_cxx.useWarnings(False)
extra_modules_defines = self._get_parser('MODULES_DEFINES:',
parsers).getValue()
if '-fmodules' in test.config.available_features:
test_cxx.compile_flags += [('-D%s' % mdef.strip()) for
mdef in extra_modules_defines]
test_cxx.addWarningFlagIfSupported('-Wno-macro-redefined')
# FIXME: libc++ debug tests #define _LIBCPP_ASSERT to override it
# If we see this we need to build the test against uniquely built
# modules.
if is_libcxx_test:
with open(test.getSourcePath(), 'r') as f:
contents = f.read()
if '#define _LIBCPP_ASSERT' in contents:
test_cxx.useModules(False)
# Dispatch the test based on its suffix. # Dispatch the test based on its suffix.
if is_sh_test: if is_sh_test:
if not isinstance(self.executor, LocalExecutor): if not isinstance(self.executor, LocalExecutor):
@@ -108,9 +149,10 @@ class LibcxxTestFormat(object):
self.execute_external, script, self.execute_external, script,
tmpBase) tmpBase)
elif is_fail_test: elif is_fail_test:
return self._evaluate_fail_test(test) return self._evaluate_fail_test(test, test_cxx, parsers)
elif is_pass_test: elif is_pass_test:
return self._evaluate_pass_test(test, tmpBase, lit_config) return self._evaluate_pass_test(test, tmpBase, lit_config,
test_cxx, parsers)
else: else:
# No other test type is supported # No other test type is supported
assert False assert False
@@ -118,21 +160,19 @@ class LibcxxTestFormat(object):
def _clean(self, exec_path): # pylint: disable=no-self-use def _clean(self, exec_path): # pylint: disable=no-self-use
libcxx.util.cleanFile(exec_path) libcxx.util.cleanFile(exec_path)
def _evaluate_pass_test(self, test, tmpBase, lit_config): def _evaluate_pass_test(self, test, tmpBase, lit_config,
test_cxx, parsers):
execDir = os.path.dirname(test.getExecPath()) execDir = os.path.dirname(test.getExecPath())
source_path = test.getSourcePath() source_path = test.getSourcePath()
with open(source_path, 'r') as f:
contents = f.read()
is_flaky = 'FLAKY_TEST' in contents
exec_path = tmpBase + '.exe' exec_path = tmpBase + '.exe'
object_path = tmpBase + '.o' object_path = tmpBase + '.o'
# Create the output directory if it does not already exist. # Create the output directory if it does not already exist.
lit.util.mkdir_p(os.path.dirname(tmpBase)) lit.util.mkdir_p(os.path.dirname(tmpBase))
try: try:
# Compile the test # Compile the test
cmd, out, err, rc = self.cxx.compileLinkTwoSteps( cmd, out, err, rc = test_cxx.compileLinkTwoSteps(
source_path, out=exec_path, object_file=object_path, source_path, out=exec_path, object_file=object_path,
cwd=execDir, env=self.compile_env) cwd=execDir)
compile_cmd = cmd compile_cmd = cmd
if rc != 0: if rc != 0:
report = libcxx.util.makeReport(cmd, out, err, rc) report = libcxx.util.makeReport(cmd, out, err, rc)
@@ -149,6 +189,7 @@ class LibcxxTestFormat(object):
# should add a `// FILE-DEP: foo.dat` to each test to track this. # should add a `// FILE-DEP: foo.dat` to each test to track this.
data_files = [os.path.join(local_cwd, f) data_files = [os.path.join(local_cwd, f)
for f in os.listdir(local_cwd) if f.endswith('.dat')] for f in os.listdir(local_cwd) if f.endswith('.dat')]
is_flaky = self._get_parser('FLAKY_TEST.', parsers).getValue()
max_retry = 3 if is_flaky else 1 max_retry = 3 if is_flaky else 1
for retry_count in range(max_retry): for retry_count in range(max_retry):
cmd, out, err, rc = self.executor.run(exec_path, [exec_path], cmd, out, err, rc = self.executor.run(exec_path, [exec_path],
@@ -170,8 +211,9 @@ class LibcxxTestFormat(object):
libcxx.util.cleanFile(object_path) libcxx.util.cleanFile(object_path)
self._clean(exec_path) self._clean(exec_path)
def _evaluate_fail_test(self, test): def _evaluate_fail_test(self, test, test_cxx, parsers):
source_path = test.getSourcePath() source_path = test.getSourcePath()
# FIXME: lift this detection into LLVM/LIT.
with open(source_path, 'r') as f: with open(source_path, 'r') as f:
contents = f.read() contents = f.read()
verify_tags = ['expected-note', 'expected-remark', 'expected-warning', verify_tags = ['expected-note', 'expected-remark', 'expected-warning',
@@ -182,18 +224,13 @@ class LibcxxTestFormat(object):
# are dependant on a template parameter when '-fsyntax-only' is passed. # are dependant on a template parameter when '-fsyntax-only' is passed.
# This is fixed in GCC 6. However for now we only pass "-fsyntax-only" # This is fixed in GCC 6. However for now we only pass "-fsyntax-only"
# when using Clang. # when using Clang.
extra_flags = [] if test_cxx.type != 'gcc':
if self.cxx.type != 'gcc': test_cxx.flags += ['-fsyntax-only']
extra_flags += ['-fsyntax-only']
if use_verify: if use_verify:
extra_flags += ['-Xclang', '-verify', test_cxx.flags += ['-Xclang', '-verify',
'-Xclang', '-verify-ignore-unexpected=note', '-Xclang', '-verify-ignore-unexpected=note',
'-ferror-limit=1024'] '-ferror-limit=1024']
cmd, out, err, rc = self.cxx.compile(source_path, out=os.devnull, cmd, out, err, rc = test_cxx.compile(source_path, out=os.devnull)
flags=extra_flags,
disable_ccache=True,
enable_warnings=False,
env=self.compile_env)
expected_rc = 0 if use_verify else 1 expected_rc = 0 if use_verify else 1
if rc == expected_rc: if rc == expected_rc:
return lit.Test.PASS, '' return lit.Test.PASS, ''

View File

@@ -23,6 +23,7 @@
// C++11 and C++03. This is important since the mangling of `lock_guard` depends // C++11 and C++03. This is important since the mangling of `lock_guard` depends
// on it being declared as a variadic template, even in C++03. // on it being declared as a variadic template, even in C++03.
// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#include <mutex> #include <mutex>
#include <string> #include <string>

View File

@@ -12,6 +12,7 @@
// <mutex> // <mutex>
// MODULES_DEFINES: _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS #define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#include <mutex> #include <mutex>

View File

@@ -12,6 +12,7 @@
// <mutex> // <mutex>
// MODULES_DEFINES: _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS #define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#include <mutex> #include <mutex>

View File

@@ -12,6 +12,7 @@
// <mutex> // <mutex>
// MODULES_DEFINES: _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS #define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#include <mutex> #include <mutex>

View File

@@ -12,6 +12,7 @@
// <mutex> // <mutex>
// MODULES_DEFINES: _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS #define _LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
#include <mutex> #include <mutex>

View File

@@ -10,6 +10,10 @@
// The test fails due to the missing is_trivially_constructible intrinsic. // The test fails due to the missing is_trivially_constructible intrinsic.
// XFAIL: gcc-4.9 // XFAIL: gcc-4.9
// The test suite needs to define the ABI macros on the command line when
// modules are enabled.
// UNSUPPORTED: -fmodules
// <utility> // <utility>
// template <class T1, class T2> struct pair // template <class T1, class T2> struct pair

View File

@@ -20,32 +20,32 @@
static int my_int = 42; static int my_int = 42;
template <int N> struct index {}; template <int N> struct index_t {};
void f(index<0>) {} void f(index_t<0>) {}
int f(index<1>) { return 0; } int f(index_t<1>) { return 0; }
int & f(index<2>) { return static_cast<int &>(my_int); } int & f(index_t<2>) { return static_cast<int &>(my_int); }
int const & f(index<3>) { return static_cast<int const &>(my_int); } int const & f(index_t<3>) { return static_cast<int const &>(my_int); }
int volatile & f(index<4>) { return static_cast<int volatile &>(my_int); } int volatile & f(index_t<4>) { return static_cast<int volatile &>(my_int); }
int const volatile & f(index<5>) { return static_cast<int const volatile &>(my_int); } int const volatile & f(index_t<5>) { return static_cast<int const volatile &>(my_int); }
int && f(index<6>) { return static_cast<int &&>(my_int); } int && f(index_t<6>) { return static_cast<int &&>(my_int); }
int const && f(index<7>) { return static_cast<int const &&>(my_int); } int const && f(index_t<7>) { return static_cast<int const &&>(my_int); }
int volatile && f(index<8>) { return static_cast<int volatile &&>(my_int); } int volatile && f(index_t<8>) { return static_cast<int volatile &&>(my_int); }
int const volatile && f(index<9>) { return static_cast<int const volatile &&>(my_int); } int const volatile && f(index_t<9>) { return static_cast<int const volatile &&>(my_int); }
int * f(index<10>) { return static_cast<int *>(&my_int); } int * f(index_t<10>) { return static_cast<int *>(&my_int); }
int const * f(index<11>) { return static_cast<int const *>(&my_int); } int const * f(index_t<11>) { return static_cast<int const *>(&my_int); }
int volatile * f(index<12>) { return static_cast<int volatile *>(&my_int); } int volatile * f(index_t<12>) { return static_cast<int volatile *>(&my_int); }
int const volatile * f(index<13>) { return static_cast<int const volatile *>(&my_int); } int const volatile * f(index_t<13>) { return static_cast<int const volatile *>(&my_int); }
template <int Func, class Expect> template <int Func, class Expect>
void test() void test()
{ {
using F = decltype(f(index<Func>{})); using F = decltype(f(index_t<Func>{}));
static_assert(std::is_same<F, Expect>::value, ""); static_assert(std::is_same<F, Expect>::value, "");
} }

View File

@@ -10,16 +10,13 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// FIXME: When modules are enabled we can't affect the contents of <mutex>
// by defining a macro
// XFAIL: -fmodules
// <mutex> // <mutex>
// template <class ...Mutex> class lock_guard; // template <class ...Mutex> class lock_guard;
// lock_guard(Mutex&..., adopt_lock_t); // lock_guard(Mutex&..., adopt_lock_t);
// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#include <mutex> #include <mutex>
#include <cassert> #include <cassert>

View File

@@ -10,16 +10,13 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// FIXME: When modules are enabled we can't affect the contents of <mutex>
// by defining a macro
// XFAIL: -fmodules
// <mutex> // <mutex>
// template <class ...Mutex> class lock_guard; // template <class ...Mutex> class lock_guard;
// lock_guard& operator=(lock_guard const&) = delete; // lock_guard& operator=(lock_guard const&) = delete;
// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#include <mutex> #include <mutex>

View File

@@ -10,16 +10,13 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// FIXME: When modules are enabled we can't affect the contents of <mutex>
// by defining a macro
// XFAIL: -fmodules
// <mutex> // <mutex>
// template <class ...Mutex> class lock_guard; // template <class ...Mutex> class lock_guard;
// lock_guard(lock_guard const&) = delete; // lock_guard(lock_guard const&) = delete;
// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#include <mutex> #include <mutex>

View File

@@ -10,16 +10,13 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// FIXME: When modules are enabled we can't affect the contents of <mutex>
// by defining a macro
// XFAIL: -fmodules
// <mutex> // <mutex>
// template <class ...Mutex> class lock_guard; // template <class ...Mutex> class lock_guard;
// explicit lock_guard(Mutex&...); // explicit lock_guard(Mutex&...);
// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#include <mutex> #include <mutex>

View File

@@ -10,16 +10,13 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// FIXME: When modules are enabled we can't affect the contents of <mutex>
// by defining a macro
// XFAIL: -fmodules
// <mutex> // <mutex>
// template <class ...Mutex> class lock_guard; // template <class ...Mutex> class lock_guard;
// explicit lock_guard(mutex_type& m); // explicit lock_guard(mutex_type& m);
// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#include <mutex> #include <mutex>
#include <cassert> #include <cassert>

View File

@@ -16,5 +16,6 @@
// dialects, including C++03, even though it is forward declared using // dialects, including C++03, even though it is forward declared using
// variadic templates. // variadic templates.
// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#include "mutex.pass.cpp" // Use the existing non-variadic test #include "mutex.pass.cpp" // Use the existing non-variadic test

View File

@@ -10,10 +10,6 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03 // UNSUPPORTED: c++98, c++03
// FIXME: When modules are enabled we can't affect the contents of <mutex>
// by defining a macro
// XFAIL: -fmodules
// <mutex> // <mutex>
// template <class Mutex> // template <class Mutex>
@@ -24,6 +20,7 @@
// ... // ...
// }; // };
// MODULES_DEFINES: _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#define _LIBCPP_ABI_VARIADIC_LOCK_GUARD #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD
#include <mutex> #include <mutex>
#include <type_traits> #include <type_traits>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03, c++11 // UNSUPPORTED: c++98, c++03, c++11
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03, c++11 // UNSUPPORTED: c++98, c++03, c++11
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++98, c++03, c++11 // UNSUPPORTED: c++98, c++03, c++11
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -9,7 +9,7 @@
// //
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// FLAKY_TEST // FLAKY_TEST.
// <mutex> // <mutex>

View File

@@ -9,7 +9,7 @@
// //
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// FLAKY_TEST // FLAKY_TEST.
// <mutex> // <mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++03, c++98, c++11, c++14 // UNSUPPORTED: c++03, c++98, c++11, c++14
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++03, c++98, c++11, c++14 // UNSUPPORTED: c++03, c++98, c++11, c++14
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++03, c++98, c++11, c++14 // UNSUPPORTED: c++03, c++98, c++11, c++14
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++03, c++98, c++11 // UNSUPPORTED: c++03, c++98, c++11
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++03, c++98, c++11 // UNSUPPORTED: c++03, c++98, c++11
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++03, c++98, c++11 // UNSUPPORTED: c++03, c++98, c++11
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++03, c++98, c++11 // UNSUPPORTED: c++03, c++98, c++11
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++03, c++98, c++11 // UNSUPPORTED: c++03, c++98, c++11
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++03, c++98, c++11 // UNSUPPORTED: c++03, c++98, c++11
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -10,7 +10,7 @@
// UNSUPPORTED: libcpp-has-no-threads // UNSUPPORTED: libcpp-has-no-threads
// UNSUPPORTED: c++03, c++98, c++11 // UNSUPPORTED: c++03, c++98, c++11
// FLAKY_TEST // FLAKY_TEST.
// <shared_mutex> // <shared_mutex>

View File

@@ -14,6 +14,7 @@
// template <class T, class... Args> // template <class T, class... Args>
// struct is_constructible; // struct is_constructible;
// MODULES_DEFINES: _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE
#define _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE #define _LIBCPP_TESTING_FALLBACK_IS_CONSTRUCTIBLE
#include <type_traits> #include <type_traits>
#include "test_macros.h" #include "test_macros.h"