CMake/ELF: replace 'extern "C++"' with exhaustive mangled expansions
Commit 946f15efb7
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>
This commit is contained in:
parent
4a6cbfbe5c
commit
e456232ad3
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user