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 11import re 12 13_warningFlags = [ 14 '-Werror', 15 '-Wall', 16 '-Wctad-maybe-unsupported', 17 '-Wextra', 18 '-Wshadow', 19 '-Wundef', 20 '-Wno-unused-command-line-argument', 21 '-Wno-attributes', 22 '-Wno-pessimizing-move', 23 '-Wno-c++11-extensions', 24 '-Wno-noexcept-type', 25 '-Wno-aligned-allocation-unavailable', 26 '-Wno-atomic-alignment', 27 28 # GCC warns about places where we might want to add sized allocation/deallocation 29 # functions, but we know better what we're doing/testing in the test suite. 30 '-Wno-sized-deallocation', 31 32 # Turn off warnings about user-defined literals with reserved suffixes. Those are 33 # just noise since we are testing the Standard Library itself. 34 '-Wno-literal-suffix', # GCC 35 '-Wno-user-defined-literals', # Clang 36 37 # GCC warns about this when TEST_IS_CONSTANT_EVALUATED is used on a non-constexpr 38 # function. (This mostely happens in C++11 mode.) 39 # TODO(mordante) investigate a solution for this issue. 40 '-Wno-tautological-compare', 41 42 # -Wstringop-overread and -Wstringop-overflow seem to be a bit buggy currently 43 '-Wno-stringop-overread', 44 '-Wno-stringop-overflow', 45 46 # These warnings should be enabled in order to support the MSVC 47 # team using the test suite; They enable the warnings below and 48 # expect the test suite to be clean. 49 '-Wsign-compare', 50 '-Wunused-variable', 51 '-Wunused-parameter', 52 '-Wunreachable-code', 53 '-Wno-unused-local-typedef', 54] 55 56_allStandards = ['c++03', 'c++11', 'c++14', 'c++17', 'c++20', 'c++2b'] 57def getStdFlag(cfg, std): 58 fallbacks = { 59 'c++11': 'c++0x', 60 'c++14': 'c++1y', 61 'c++17': 'c++1z', 62 'c++20': 'c++2a', 63 } 64 if hasCompileFlag(cfg, '-std='+std): 65 return '-std='+std 66 if std in fallbacks and hasCompileFlag(cfg, '-std='+fallbacks[std]): 67 return '-std='+fallbacks[std] 68 return None 69 70DEFAULT_PARAMETERS = [ 71 Parameter(name='target_triple', type=str, 72 help="The target triple to compile the test suite for. This must be " 73 "compatible with the target that the tests will be run on.", 74 actions=lambda triple: filter(None, [ 75 AddFeature('target={}'.format(triple)), 76 AddFlagIfSupported('--target={}'.format(triple)), 77 AddSubstitution('%{triple}', triple) 78 ])), 79 80 Parameter(name='std', choices=_allStandards, type=str, 81 help="The version of the standard to compile the test suite with.", 82 default=lambda cfg: next(s for s in reversed(_allStandards) if getStdFlag(cfg, s)), 83 actions=lambda std: [ 84 AddFeature(std), 85 AddSubstitution('%{cxx_std}', re.sub('\+','x', std)), 86 AddCompileFlag(lambda cfg: getStdFlag(cfg, std)), 87 ]), 88 89 Parameter(name='enable_modules', choices=[True, False], type=bool, default=False, 90 help="Whether to build the test suite with Clang modules enabled.", 91 actions=lambda modules: [ 92 AddFeature('modules-build'), 93 AddCompileFlag('-fmodules'), 94 AddCompileFlag('-fcxx-modules'), # AppleClang disregards -fmodules entirely when compiling C++. This enables modules for C++. 95 ] if modules else []), 96 97 Parameter(name='enable_exceptions', choices=[True, False], type=bool, default=True, 98 help="Whether to enable exceptions when compiling the test suite.", 99 actions=lambda exceptions: [] if exceptions else [ 100 AddFeature('no-exceptions'), 101 AddCompileFlag('-fno-exceptions') 102 ]), 103 104 Parameter(name='enable_rtti', choices=[True, False], type=bool, default=True, 105 help="Whether to enable RTTI when compiling the test suite.", 106 actions=lambda rtti: [] if rtti else [ 107 AddFeature('no-rtti'), 108 AddCompileFlag('-fno-rtti') 109 ]), 110 111 Parameter(name='stdlib', choices=['llvm-libc++', 'apple-libc++', 'libstdc++', 'msvc'], type=str, default='llvm-libc++', 112 help="""The C++ Standard Library implementation being tested. 113 114 Note that this parameter can also be used to encode different 'flavors' of the same 115 standard library, such as libc++ as shipped by a different vendor, if it has different 116 properties worth testing. 117 118 The Standard libraries currently supported are: 119 - llvm-libc++: The 'upstream' libc++ as shipped with LLVM. 120 - apple-libc++: libc++ as shipped by Apple. This is basically like the LLVM one, but 121 there are a few differences like installation paths and the use of 122 universal dylibs. 123 - libstdc++: The GNU C++ library typically shipped with GCC. 124 - msvc: The Microsoft implementation of the C++ Standard Library. 125 """, 126 actions=lambda stdlib: filter(None, [ 127 AddFeature('stdlib={}'.format(stdlib)), 128 # Also add an umbrella feature 'stdlib=libc++' for all flavors of libc++, to simplify 129 # the test suite. 130 AddFeature('stdlib=libc++') if re.match('.+-libc\+\+', stdlib) else None 131 ])), 132 133 Parameter(name='enable_warnings', choices=[True, False], type=bool, default=True, 134 help="Whether to enable warnings when compiling the test suite.", 135 actions=lambda warnings: [] if not warnings else 136 [AddOptionalWarningFlag(w) for w in _warningFlags] + 137 [AddCompileFlag('-D_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER')] 138 ), 139 140 Parameter(name='use_sanitizer', choices=['', 'Address', 'HWAddress', 'Undefined', 'Memory', 'MemoryWithOrigins', 'Thread', 'DataFlow', 'Leaks'], type=str, default='', 141 help="An optional sanitizer to enable when building and running the test suite.", 142 actions=lambda sanitizer: filter(None, [ 143 AddFlag('-g -fno-omit-frame-pointer') if sanitizer else None, 144 145 AddFlag('-fsanitize=undefined -fno-sanitize=float-divide-by-zero -fno-sanitize-recover=all') if sanitizer == 'Undefined' else None, 146 AddFeature('ubsan') if sanitizer == 'Undefined' else None, 147 148 AddFlag('-fsanitize=address') if sanitizer == 'Address' else None, 149 AddFeature('asan') if sanitizer == 'Address' else None, 150 151 AddFlag('-fsanitize=hwaddress') if sanitizer == 'HWAddress' else None, 152 AddFeature('hwasan') if sanitizer == 'HWAddress' else None, 153 154 AddFlag('-fsanitize=memory') if sanitizer in ['Memory', 'MemoryWithOrigins'] else None, 155 AddFeature('msan') if sanitizer in ['Memory', 'MemoryWithOrigins'] else None, 156 AddFlag('-fsanitize-memory-track-origins') if sanitizer == 'MemoryWithOrigins' else None, 157 158 AddFlag('-fsanitize=thread') if sanitizer == 'Thread' else None, 159 AddFeature('tsan') if sanitizer == 'Thread' else None, 160 161 AddFlag('-fsanitize=dataflow') if sanitizer == 'DataFlow' else None, 162 AddFlag('-fsanitize=leaks') if sanitizer == 'Leaks' else None, 163 164 AddFeature('sanitizer-new-delete') if sanitizer in ['Address', 'HWAddress', 'Memory', 'MemoryWithOrigins', 'Thread'] else None, 165 ])), 166 167 Parameter(name='enable_experimental', choices=[True, False], type=bool, default=True, 168 help="Whether to enable tests for experimental C++ Library features.", 169 actions=lambda experimental: [ 170 # When linking in MSVC mode via the Clang driver, a -l<foo> 171 # maps to <foo>.lib, so we need to use -llibc++experimental here 172 # to make it link against the static libc++experimental.lib. 173 # We can't check for the feature 'msvc' in available_features 174 # as those features are added after processing parameters. 175 AddFeature('c++experimental'), 176 PrependLinkFlag(lambda cfg: '-llibc++experimental' if _isMSVC(cfg) else '-lc++experimental'), 177 AddCompileFlag('-D_LIBCPP_ENABLE_EXPERIMENTAL'), 178 ] if experimental else [ 179 AddFeature('libcpp-has-no-incomplete-format'), 180 ]), 181 182 Parameter(name='long_tests', choices=[True, False], type=bool, default=True, 183 help="Whether to enable tests that take longer to run. This can be useful when running on a very slow device.", 184 actions=lambda enabled: [] if not enabled else [ 185 AddFeature('long_tests') 186 ]), 187 188 Parameter(name='enable_assertions', choices=[True, False], type=bool, default=False, 189 help="Whether to enable assertions when compiling the test suite. This is only meaningful when " 190 "running the tests against libc++.", 191 actions=lambda assertions: [ 192 AddCompileFlag('-D_LIBCPP_ENABLE_ASSERTIONS=1'), 193 AddFeature('libcpp-has-assertions') 194 ] if assertions else []), 195 196 Parameter(name='additional_features', type=list, default=[], 197 help="A comma-delimited list of additional features that will be enabled when running the tests. " 198 "This should be used sparingly since specifying ad-hoc features manually is error-prone and " 199 "brittle in the long run as changes are made to the test suite.", 200 actions=lambda features: [AddFeature(f) for f in features]), 201 202 Parameter(name='enable_transitive_includes', choices=[True, False], type=bool, default=True, 203 help="Whether to enable backwards-compatibility transitive includes when running the tests. This " 204 "is provided to ensure that the trimmed-down version of libc++ does not bit-rot in between " 205 "points at which we bulk-remove transitive includes.", 206 actions=lambda enabled: [] if enabled else [ 207 AddFeature('transitive-includes-disabled'), 208 AddCompileFlag('-D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES') 209 ]), 210] 211 212DEFAULT_PARAMETERS += [ 213 Parameter(name='use_system_cxx_lib', choices=[True, False], type=bool, default=False, 214 help=""" 215 Whether the test suite is being *run* against the library shipped on the 216 target triple in use, as opposed to the trunk library. 217 218 When vendor-specific availability annotations are enabled, we add the 219 'use_system_cxx_lib' Lit feature to allow writing XFAIL or UNSUPPORTED 220 markup for tests that are known to fail on a particular triple. 221 222 That feature can be used to XFAIL a test that fails when deployed on (or is 223 compiled for) an older system. For example, if the test exhibits a bug in the 224 libc on a particular system version, or if the test uses a symbol that is not 225 available on an older version of the dylib, it can be marked as XFAIL with 226 the above feature. 227 228 It is sometimes useful to check that a test fails specifically when compiled 229 for a given deployment target. For example, this is the case when testing 230 availability markup, where we want to make sure that using the annotated 231 facility on a deployment target that doesn't support it will fail at compile 232 time, not at runtime. This can be achieved by creating a `.compile.pass.cpp` 233 and XFAILing it for the right deployment target. If the test doesn't fail at 234 compile-time like it's supposed to, the test will XPASS. Another option is to 235 create a `.verify.cpp` test that checks for the right errors, and mark that 236 test as requiring `use_system_cxx_lib && <target>`. 237 """, 238 actions=lambda useSystem: [ 239 AddFeature('use_system_cxx_lib') 240 ] if useSystem else [ 241 # If we're testing upstream libc++, disable availability markup, 242 # which is not relevant for non-shipped flavors of libc++. 243 AddCompileFlag('-D_LIBCPP_DISABLE_AVAILABILITY') 244 ]) 245] 246