target_link_libraries(${target} PRIVATE gcc_s)
endif()
- if (LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB)
+ if (LIBCXX_HAS_ATOMIC_LIB)
target_link_libraries(${target} PRIVATE atomic)
endif()
+++ /dev/null
-INCLUDE(CheckCXXSourceCompiles)
-
-# Sometimes linking against libatomic is required for atomic ops, if
-# the platform doesn't support lock-free atomics.
-#
-# We could modify LLVM's CheckAtomic module and have it check for 64-bit
-# atomics instead. However, we would like to avoid careless uses of 64-bit
-# atomics inside LLVM over time on 32-bit platforms.
-
-function(check_cxx_atomics varname)
- set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
- set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs -std=c++11 -nostdinc++ -isystem ${LIBCXX_SOURCE_DIR}/include")
- if (${LIBCXX_GCC_TOOLCHAIN})
- set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} --gcc-toolchain=${LIBCXX_GCC_TOOLCHAIN}")
- endif()
- if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize)
- set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all")
- endif()
- if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage)
- set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters")
- endif()
- check_cxx_source_compiles("
-#include <cstdint>
-#include <atomic>
-std::atomic<uintptr_t> x;
-std::atomic<uintmax_t> y;
-int main(int, char**) {
- return x + y;
-}
-" ${varname})
- set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
-endfunction(check_cxx_atomics)
-
-# Perform the check for 64bit atomics without libatomic. It may have been
-# added to the required libraries during in the configuration of LLVM, which
-# would cause the check for CXX atomics without libatomic to incorrectly pass.
-if (CMAKE_REQUIRED_LIBRARIES)
- set(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
- list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES "atomic")
- check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
- set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES})
-endif()
-
-check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
-# If not, check if the library exists, and atomics work with it.
-if(NOT LIBCXX_HAVE_CXX_ATOMICS_WITHOUT_LIB)
- if(LIBCXX_HAS_ATOMIC_LIB)
- list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
- check_cxx_atomics(LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB)
- if (NOT LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB)
- message(WARNING "Host compiler must support std::atomic!")
- endif()
- else()
- message(WARNING "Host compiler appears to require libatomic, but cannot find it.")
- endif()
-endif()
cmake_pop_check_state()
endif()
-if(NOT WIN32 OR MINGW)
- include(CheckLibcxxAtomic)
-endif()
-
# Check libraries
if(WIN32 AND NOT MINGW)
# TODO(compnerd) do we want to support an emulation layer that allows for the
set(LIBCXX_HAS_M_LIB NO)
set(LIBCXX_HAS_RT_LIB NO)
set(LIBCXX_HAS_SYSTEM_LIB NO)
+ set(LIBCXX_HAS_ATOMIC_LIB NO)
elseif(APPLE)
check_library_exists(System write "" LIBCXX_HAS_SYSTEM_LIB)
set(LIBCXX_HAS_PTHREAD_LIB NO)
set(LIBCXX_HAS_M_LIB NO)
set(LIBCXX_HAS_RT_LIB NO)
+ set(LIBCXX_HAS_ATOMIC_LIB NO)
elseif(FUCHSIA)
set(LIBCXX_HAS_M_LIB NO)
set(LIBCXX_HAS_PTHREAD_LIB NO)
set(LIBCXX_HAS_RT_LIB NO)
set(LIBCXX_HAS_SYSTEM_LIB NO)
+ check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
else()
check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB)
check_library_exists(m ccos "" LIBCXX_HAS_M_LIB)
check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
set(LIBCXX_HAS_SYSTEM_LIB NO)
+ check_library_exists(atomic __atomic_fetch_add_8 "" LIBCXX_HAS_ATOMIC_LIB)
endif()
//===----------------------------------------------------------------------===//
//
// UNSUPPORTED: libcpp-has-no-threads, c++03
-// REQUIRES: libatomic
-// FILE_DEPENDENCIES: %t.exe
-// RUN: %{build} -latomic
-// RUN: %{run}
-//
+// REQUIRES: non-lockfree-atomics
+
// GCC currently fails because it needs -fabi-version=6 to fix mangling of
// std::atomic when used with __attribute__((vector(X))).
// XFAIL: gcc
self.assertTrue(dsl.hasCompileFlag(self.config, '-O1 -Dhello'))
+class TestSourceBuilds(SetupConfigs):
+ """
+ Tests for libcxx.test.dsl.sourceBuilds
+ """
+ def test_valid_program_builds(self):
+ source = """int main(int, char**) { }"""
+ self.assertTrue(dsl.sourceBuilds(self.config, source))
+
+ def test_compilation_error_fails(self):
+ source = """in main(int, char**) { }"""
+ self.assertFalse(dsl.sourceBuilds(self.config, source))
+
+ def test_link_error_fails(self):
+ source = """extern void this_isnt_defined_anywhere();
+ int main(int, char**) { this_isnt_defined_anywhere(); }"""
+ self.assertFalse(dsl.sourceBuilds(self.config, source))
+
+
class TestHasLocale(SetupConfigs):
"""
Tests for libcxx.test.dsl.hasLocale
config.llvm_unwinder = @LIBCXXABI_USE_LLVM_UNWINDER@
config.builtins_library = "@LIBCXX_BUILTINS_LIBRARY@"
config.has_libatomic = @LIBCXX_HAS_ATOMIC_LIB@
-config.use_libatomic = @LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB@
config.debug_build = @LIBCXX_DEBUG_BUILD@
config.libcxxabi_shared = @LIBCXX_LINK_TESTS_WITH_SHARED_LIBCXXABI@
config.cxx_ext_threads = @LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY@
if not self.get_lit_bool('enable_filesystem', default=True):
self.config.available_features.add('c++filesystem-disabled')
- if self.get_lit_bool('has_libatomic', False):
- self.config.available_features.add('libatomic')
-
if self.target_info.is_windows():
self.config.available_features.add('windows')
if self.cxx_stdlib_under_test == 'libc++':
def __exit__(self, *args): os.remove(tmp.name)
return TestWrapper(suite, pathInSuite, config)
+def sourceBuilds(config, source):
+ """
+ Return whether the program in the given string builds successfully.
+
+ This is done by compiling and linking a program that consists of the given
+ source with the %{cxx} substitution, and seeing whether that succeeds.
+ """
+ with _makeConfigTest(config) as test:
+ with open(test.getSourcePath(), 'w') as sourceFile:
+ sourceFile.write(source)
+ commands = [
+ "mkdir -p %T",
+ "%{cxx} -xc++ %s %{flags} %{compile_flags} %{link_flags} -o %t.exe"
+ ]
+ commands = libcxx.test.newformat.parseScript(test, preamble=commands, fileDependencies=['%t.exe'])
+ out, err, exitCode, timeoutInfo = _executeScriptInternal(test, commands)
+ cleanup = libcxx.test.newformat.parseScript(test, preamble=['rm %t.exe'], fileDependencies=[])
+ _executeScriptInternal(test, cleanup)
+ return exitCode == 0
+
def hasCompileFlag(config, flag):
"""
Return whether the compiler in the configuration supports a given compiler flag.
Feature(name='objective-c++', when=lambda cfg: hasCompileFlag(cfg, '-xobjective-c++ -fobjc-arc')),
Feature(name='diagnose-if-support', when=lambda cfg: hasCompileFlag(cfg, '-Wuser-defined-warnings'), compileFlag='-Wuser-defined-warnings'),
Feature(name='modules-support', when=lambda cfg: hasCompileFlag(cfg, '-fmodules')),
+ Feature(name='non-lockfree-atomics', when=lambda cfg: sourceBuilds(cfg, """
+ #include <atomic>
+ struct Large { int storage[100]; };
+ std::atomic<Large> x;
+ int main(int, char**) { return x.load(), x.is_lock_free(); }
+ """)),
Feature(name='apple-clang', when=_isAppleClang),
Feature(name=lambda cfg: 'apple-clang-{__clang_major__}'.format(**compilerMacros(cfg)), when=_isAppleClang),
flags += [builtins_lib]
else:
flags += ['-lgcc']
- use_libatomic = self.full_config.get_lit_bool('use_libatomic', False)
- if use_libatomic:
+ has_libatomic = self.full_config.get_lit_bool('has_libatomic', False)
+ if has_libatomic:
flags += ['-latomic']
san = self.full_config.get_lit_conf('use_sanitizer', '').strip()
if san: