1#===----------------------------------------------------------------------===##
2#
3# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4# See https://llvm.org/LICENSE.txt for license information.
5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6#
7#===----------------------------------------------------------------------===##
8
9from libcxx.test.dsl import *
10from libcxx.test.features import _isMSVC
11
12_warningFlags = [
13  '-Werror',
14  '-Wall',
15  '-Wextra',
16  '-Wshadow',
17  '-Wundef',
18  '-Wno-unused-command-line-argument',
19  '-Wno-attributes',
20  '-Wno-pessimizing-move',
21  '-Wno-c++11-extensions',
22  '-Wno-user-defined-literals',
23  '-Wno-noexcept-type',
24  '-Wno-aligned-allocation-unavailable',
25  '-Wno-atomic-alignment',
26
27  # GCC warns about places where we might want to add sized allocation/deallocation
28  # functions, but we know better what we're doing/testing in the test suite.
29  '-Wno-sized-deallocation',
30
31  # These warnings should be enabled in order to support the MSVC
32  # team using the test suite; They enable the warnings below and
33  # expect the test suite to be clean.
34  '-Wsign-compare',
35  '-Wunused-variable',
36  '-Wunused-parameter',
37  '-Wunreachable-code',
38  '-Wno-unused-local-typedef',
39]
40
41_allStandards = ['c++03', 'c++11', 'c++14', 'c++17', 'c++20', 'c++2b']
42def getStdFlag(cfg, std):
43  fallbacks = {
44    'c++11': 'c++0x',
45    'c++14': 'c++1y',
46    'c++17': 'c++1z',
47    'c++20': 'c++2a',
48  }
49  if hasCompileFlag(cfg, '-std='+std):
50    return '-std='+std
51  if std in fallbacks and hasCompileFlag(cfg, '-std='+fallbacks[std]):
52    return '-std='+fallbacks[std]
53  return None
54
55DEFAULT_PARAMETERS = [
56  # Core parameters of the test suite
57  Parameter(name='target_triple', type=str, default=getHostTriple,
58            help="The target triple to compile the test suite for. This must be "
59                 "compatible with the target that the tests will be run on.",
60            actions=lambda triple: filter(None, [
61              AddFeature(triple),
62              AddFlagIfSupported('--target={}'.format(triple)),
63              AddFeature('linux-gnu') if re.match(r'^.*-linux-gnu', triple) else None,
64              AddFeature('x86_64-linux') if re.match(r'^x86_64.*-linux', triple) else None,
65              AddFeature('x86_64-apple') if re.match(r'^x86_64.*-apple', triple) else None,
66              AddFeature('target-x86') if re.match(r'^i.86.*', triple) else None,
67              AddFeature('target-x86_64') if re.match(r'^x86_64.*', triple) else None,
68              AddFeature('target-aarch64') if re.match(r'^aarch64.*', triple) else None,
69              AddFeature('target-arm') if re.match(r'^arm.*', triple) else None,
70            ])),
71
72  Parameter(name='std', choices=_allStandards, type=str,
73            help="The version of the standard to compile the test suite with.",
74            default=lambda cfg: next(s for s in reversed(_allStandards) if getStdFlag(cfg, s)),
75            actions=lambda std: [
76              AddFeature(std),
77              AddCompileFlag(lambda cfg: getStdFlag(cfg, std)),
78            ]),
79
80  Parameter(name='enable_exceptions', choices=[True, False], type=bool, default=True,
81            help="Whether to enable exceptions when compiling the test suite.",
82            actions=lambda exceptions: [] if exceptions else [
83              AddFeature('no-exceptions'),
84              AddCompileFlag('-fno-exceptions')
85            ]),
86
87  Parameter(name='enable_rtti', choices=[True, False], type=bool, default=True,
88            help="Whether to enable RTTI when compiling the test suite.",
89            actions=lambda rtti: [] if rtti else [
90              AddFeature('no-rtti'),
91              AddCompileFlag('-fno-rtti')
92            ]),
93
94  Parameter(name='stdlib', choices=['libc++', 'libstdc++', 'msvc'], type=str, default='libc++',
95            help="The C++ Standard Library implementation being tested.",
96            actions=lambda stdlib: [
97              AddFeature(stdlib)
98            ]),
99
100  Parameter(name='enable_warnings', choices=[True, False], type=bool, default=True,
101            help="Whether to enable warnings when compiling the test suite.",
102            actions=lambda warnings: [] if not warnings else [
103              AddOptionalWarningFlag(w) for w in _warningFlags
104            ]),
105
106  Parameter(name='debug_level', choices=['', '0', '1'], type=str, default='',
107            help="The debugging level to enable in the test suite.",
108            actions=lambda debugLevel: [] if debugLevel == '' else [
109              AddFeature('debug_level={}'.format(debugLevel)),
110              AddCompileFlag('-D_LIBCPP_DEBUG={}'.format(debugLevel))
111            ]),
112
113  Parameter(name='use_sanitizer', choices=['', 'Address', 'Undefined', 'Memory', 'MemoryWithOrigins', 'Thread', 'DataFlow', 'Leaks'], type=str, default='',
114            help="An optional sanitizer to enable when building and running the test suite.",
115            actions=lambda sanitizer: filter(None, [
116              AddFlag('-g -fno-omit-frame-pointer') if sanitizer else None,
117
118              AddFlag('-fsanitize=undefined -fno-sanitize=float-divide-by-zero -fno-sanitize-recover=all') if sanitizer == 'Undefined' else None,
119              AddFeature('ubsan')                                                                          if sanitizer == 'Undefined' else None,
120
121              AddFlag('-fsanitize=address') if sanitizer == 'Address' else None,
122              AddFeature('asan')            if sanitizer == 'Address' else None,
123
124              AddFlag('-fsanitize=memory')               if sanitizer in ['Memory', 'MemoryWithOrigins'] else None,
125              AddFeature('msan')                         if sanitizer in ['Memory', 'MemoryWithOrigins'] else None,
126              AddFlag('-fsanitize-memory-track-origins') if sanitizer == 'MemoryWithOrigins' else None,
127
128              AddFlag('-fsanitize=thread') if sanitizer == 'Thread' else None,
129              AddFeature('tsan')           if sanitizer == 'Thread' else None,
130
131              AddFlag('-fsanitize=dataflow') if sanitizer == 'DataFlow' else None,
132              AddFlag('-fsanitize=leaks') if sanitizer == 'Leaks' else None,
133
134              AddFeature('sanitizer-new-delete') if sanitizer in ['Address', 'Memory', 'MemoryWithOrigins', 'Thread'] else None,
135            ])),
136
137  # Parameters to enable or disable parts of the test suite
138  Parameter(name='enable_experimental', choices=[True, False], type=bool, default=False,
139            help="Whether to enable tests for experimental C++ libraries (typically Library Fundamentals TSes).",
140            actions=lambda experimental: [] if not experimental else [
141              AddFeature('c++experimental'),
142              # When linking in MSVC mode via the Clang driver, a -l<foo>
143              # maps to <foo>.lib, so we need to use -llibc++experimental here
144              # to make it link against the static libc++experimental.lib.
145              # We can't check for the feature 'msvc' in available_features
146              # as those features are added after processing parameters.
147              PrependLinkFlag(lambda config: '-llibc++experimental' if _isMSVC(config) else '-lc++experimental')
148            ]),
149
150  Parameter(name='long_tests', choices=[True, False], type=bool, default=True,
151            help="Whether to enable tests that take longer to run. This can be useful when running on a very slow device.",
152            actions=lambda enabled: [] if not enabled else [
153              AddFeature('long_tests')
154            ]),
155
156  Parameter(name='enable_debug_tests', choices=[True, False], type=bool, default=True,
157            help="Whether to enable tests that exercise the libc++ debugging mode.",
158            actions=lambda enabled: [] if enabled else [
159              AddFeature('libcxx-no-debug-mode')
160            ]),
161]
162
163DEFAULT_PARAMETERS += [
164  Parameter(name='use_system_cxx_lib', choices=[True, False], type=bool, default=False,
165            help="""
166    Whether the test suite is being *run* against the library shipped on the
167    target triple in use, as opposed to the trunk library.
168
169    When vendor-specific availability annotations are enabled, we add the
170    'use_system_cxx_lib' Lit feature to allow writing XFAIL or UNSUPPORTED
171    markup for tests that are known to fail on a particular triple.
172
173    That feature can be used to XFAIL a test that fails when deployed on (or is
174    compiled for) an older system. For example, if the test exhibits a bug in the
175    libc on a particular system version, or if the test uses a symbol that is not
176    available on an older version of the dylib, it can be marked as XFAIL with
177    the above feature.
178
179    It is sometimes useful to check that a test fails specifically when compiled
180    for a given deployment target. For example, this is the case when testing
181    availability markup, where we want to make sure that using the annotated
182    facility on a deployment target that doesn't support it will fail at compile
183    time, not at runtime. This can be achieved by creating a `.compile.pass.cpp`
184    and XFAILing it for the right deployment target. If the test doesn't fail at
185    compile-time like it's supposed to, the test will XPASS. Another option is to
186    create a `.verify.cpp` test that checks for the right errors, and mark that
187    test as requiring `use_system_cxx_lib && <target>`.
188    """,
189    actions=lambda useSystem: [
190      AddFeature('use_system_cxx_lib')
191    ] if useSystem else [
192      # If we're testing upstream libc++, disable availability markup,
193      # which is not relevant for non-shipped flavors of libc++.
194      AddCompileFlag('-D_LIBCPP_DISABLE_AVAILABILITY')
195    ])
196]
197