summaryrefslogtreecommitdiffstats
path: root/cmake/QtFlagHandlingHelpers.cmake
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-09-12 16:15:14 -0700
committerThiago Macieira <thiago.macieira@intel.com>2023-09-19 17:13:56 -0700
commite456232ad3cef052980a07a0a9a9f5fa49b65ba3 (patch)
treeaa838713397ae44b30b368164a424a7ea2c66411 /cmake/QtFlagHandlingHelpers.cmake
parent4a6cbfbe5c90158ab2f4afed3d188dae3ec0ea85 (diff)
CMake/ELF: replace 'extern "C++"' with exhaustive mangled expansions
Commit 946f15efb76fffda37b77f7d194d679b904305b1 added the line extern "C++" { std::* }; but that was too good to be true. The intention was to catch Standard Library inline symbols that got emitted in our own libraries, not use of Standard Library types in our symbols. Unfortunately, that glob expression matches the demangling literally and return types for templates are demangled in their usual position to the left of the function name. For example, std::random_device qFoo(); // mangles as _Z4qFoov → "qFoo()" but template <typename T> T qFoo(); template std::random_device qFoo<std::random_device>(); mangles as _Z4qFooISt13random_deviceET_v and that demangles to "std::random_device qFoo<std::random_device>()". Therefore, we replace that with a full expansion according to the mangling scheme. This includes a minor fix for the RTTI symbols, to match nested names too (those with "N" in the name). It can't match virtual override thunks ("Tv" and "Th"), because those have variable length names and the matching is done by fnmatch(), not regex. Pick-to: 6.6 Change-Id: I9d43e5b91eb142d6945cfffd178449cf68669cb6 Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
Diffstat (limited to 'cmake/QtFlagHandlingHelpers.cmake')
-rw-r--r--cmake/QtFlagHandlingHelpers.cmake34
1 files changed, 30 insertions, 4 deletions
diff --git a/cmake/QtFlagHandlingHelpers.cmake b/cmake/QtFlagHandlingHelpers.cmake
index bc393655bb..f93aaef841 100644
--- a/cmake/QtFlagHandlingHelpers.cmake
+++ b/cmake/QtFlagHandlingHelpers.cmake
@@ -23,10 +23,36 @@ function(qt_internal_add_linker_version_script target)
endif()
if(TEST_ld_version_script)
- set(contents "NonQt { local:\n")
- string(APPEND contents " _ZT?S*;\n") # {typeinfo {,name},vtable,VTT} for std::
- string(APPEND contents " extern \"C++\" { std::*; };\n")
- string(APPEND contents "};\nQt_${PROJECT_VERSION_MAJOR}_PRIVATE_API { qt_private_api_tag*;\n")
+ # Create a list of mangled symbol matches for all "std::" symbols. This
+ # list will catch most symbols, but will miss global-namespace symbols
+ # that only have std parameters.
+ # See https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangle.name for reference
+ set(contents "NonQt {\nlocal:")
+
+ # For types: vtable, VTT, typeinfo, typeinfo name
+ foreach(ptrqualifier "" "P" "PK") # T, T *, const T * (volatile ignored)
+ string(APPEND contents "\n _ZT[VTIS]${ptrqualifier}S*;"
+ "_ZT[VTIS]${ptrqualifier}NS*;")
+ endforeach()
+
+ # For functions and variables
+ foreach(special ""
+ "G[VR]" # guard variables, extended-lifetime references
+ "GTt") # transaction entry points
+ foreach(cvqualifier "" "[VK]" "VK") # plain, const|volatile, const volatile
+ string(APPEND contents "\n ")
+ foreach(refqualifier "" "[RO]") # plain, & or &&
+ # For names in the std:: namespace, compression applies
+ # (https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression)
+ string(APPEND contents
+ " _Z${special}${cvqualifier}${refqualifier}S*;" # plain
+ " _Z${special}N${cvqualifier}${refqualifier}S*;" # nested name
+ )
+ endforeach()
+ endforeach()
+ endforeach()
+
+ string(APPEND contents "\n};\nQt_${PROJECT_VERSION_MAJOR}_PRIVATE_API { qt_private_api_tag*;\n")
if(arg_PRIVATE_HEADERS)
foreach(ph ${arg_PRIVATE_HEADERS})
string(APPEND contents " @FILE:${ph}@\n")