[libcxx-commits] [libcxx] 4940caa - [libcxx] [test] Don't use header defines for detecting linking against a DLL

Martin Storsjö via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jun 6 13:19:31 PDT 2022


Author: Martin Storsjö
Date: 2022-06-06T23:19:22+03:00
New Revision: 4940caaebbe04af55c0bd36d2ad291fa75932260

URL: https://github.com/llvm/llvm-project/commit/4940caaebbe04af55c0bd36d2ad291fa75932260
DIFF: https://github.com/llvm/llvm-project/commit/4940caaebbe04af55c0bd36d2ad291fa75932260.diff

LOG: [libcxx] [test] Don't use header defines for detecting linking against a DLL

In clang-cl/MSVC environments, linking against a DLL C++ standard
library requires having dllimport attributes in the headers; this
has been used for detecting whether the tests link against a DLL,
by looking at the libc++ specific define
_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS.

In mingw environments, thanks to slightly different code generation
and a couple linker tricks, it's possible to link against a DLL C++
standard library without dllimport attributes. Therefore, don't
rely on the libc++ specific header define for the detection.

Replace the detection with a runtime test.

Differential Revision: https://reviews.llvm.org/D125922

Added: 
    

Modified: 
    libcxx/test/support/test_macros.h
    libcxx/utils/libcxx/test/features.py

Removed: 
    


################################################################################
diff  --git a/libcxx/test/support/test_macros.h b/libcxx/test/support/test_macros.h
index 60dd8e7e3b48f..4502574922198 100644
--- a/libcxx/test/support/test_macros.h
+++ b/libcxx/test/support/test_macros.h
@@ -306,8 +306,7 @@ inline void DoNotOptimize(Tp const& value) {
 #define TEST_NOT_WIN32(...) __VA_ARGS__
 #endif
 
-#if (defined(_WIN32) && !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)) ||   \
-    defined(__MVS__) || defined(_AIX)
+#if defined(TEST_WINDOWS_DLL) ||defined(__MVS__) || defined(_AIX)
 // Macros for waiving cases when we can't count allocations done within
 // the library implementation.
 //
@@ -325,8 +324,7 @@ inline void DoNotOptimize(Tp const& value) {
 #define TEST_SUPPORTS_LIBRARY_INTERNAL_ALLOCATIONS 1
 #endif
 
-#if (defined(_WIN32) && !defined(_MSC_VER) &&                                  \
-     !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)) ||                      \
+#if (defined(TEST_WINDOWS_DLL) && !defined(_MSC_VER)) ||                      \
     defined(__MVS__)
 // Normally, a replaced e.g. 'operator new' ends up used if the user code
 // does a call to e.g. 'operator new[]'; it's enough to replace the base

diff  --git a/libcxx/utils/libcxx/test/features.py b/libcxx/utils/libcxx/test/features.py
index 859f5d1467cac..20fdbe9bba449 100644
--- a/libcxx/utils/libcxx/test/features.py
+++ b/libcxx/utils/libcxx/test/features.py
@@ -222,7 +222,34 @@ def _hasSuitableClangTidy(cfg):
 DEFAULT_FEATURES += [
   Feature(name='darwin', when=lambda cfg: '__APPLE__' in compilerMacros(cfg)),
   Feature(name='windows', when=lambda cfg: '_WIN32' in compilerMacros(cfg)),
-  Feature(name='windows-dll', when=lambda cfg: '_WIN32' in compilerMacros(cfg) and not '_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS' in compilerMacros(cfg)),
+  Feature(name='windows-dll', when=lambda cfg: '_WIN32' in compilerMacros(cfg) and programSucceeds(cfg, """
+            #include <iostream>
+            #include <windows.h>
+            #include <winnt.h>
+            int main(int, char**) {
+              // Get a pointer to a data member that gets linked from the C++
+              // library. This must be a data member (functions can get
+              // thunk inside the calling executable), and must not be
+              // something that is defined inline in headers.
+              void *ptr = &std::cout;
+              // Get a handle to the current main executable.
+              void *exe = GetModuleHandle(NULL);
+              // The handle points at the PE image header. Navigate through
+              // the header structure to find the size of the PE image (the
+              // executable).
+              PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)exe;
+              PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)((BYTE *)dosheader + dosheader->e_lfanew);
+              PIMAGE_OPTIONAL_HEADER peheader = &ntheader->OptionalHeader;
+              void *exeend = (BYTE*)exe + peheader->SizeOfImage;
+              // Check if the tested pointer - the data symbol from the
+              // C++ library - is located within the exe.
+              if (ptr >= exe && ptr <= exeend)
+                return 1;
+              // Return success if it was outside of the executable, i.e.
+              // loaded from a DLL.
+              return 0;
+            }
+          """), actions=[AddCompileFlag('-DTEST_WINDOWS_DLL')]),
   Feature(name='linux', when=lambda cfg: '__linux__' in compilerMacros(cfg)),
   Feature(name='netbsd', when=lambda cfg: '__NetBSD__' in compilerMacros(cfg)),
   Feature(name='freebsd', when=lambda cfg: '__FreeBSD__' in compilerMacros(cfg))


        


More information about the libcxx-commits mailing list