Skip to content

[cxx-interop] Fix linker errors when a template is used from different modules #42222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 7, 2022

Conversation

egorzhdan
Copy link
Contributor

If a templated C++ class is used from two different C++ modules, and those modules are included in Swift, Clang will create different two different redecls for the class & its methods.

For each of the methods, only one of the redecls would actually have a body, the other would have empty bodies. That prevents ClangDeclFinder from properly finding the symbols referenced from a method body, leading to a linker error in some cases, when the first redecl is missing a body.

This prevents std::string from being used on Linux:

/tmp/use-std-string-2dd593.o:use-std-string-2dd593.o:function void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag): error: undefined reference to 'bool __gnu_cxx::__is_null_pointer<char>(char*)'
/tmp/use-std-string-2dd593.o:use-std-string-2dd593.o:function void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag): error: undefined reference to 'std::iterator_traits<char*>::difference_type std::distance<char*>(char*, char*)'
clang-13: error: linker command failed with exit code 1 (use -v to see invocation)
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)

@egorzhdan egorzhdan requested review from hyp and zoecarver April 6, 2022 19:59
@egorzhdan egorzhdan added the c++ interop Feature: Interoperability with C++ label Apr 6, 2022
@egorzhdan
Copy link
Contributor Author

@swift-ci please smoke test

@egorzhdan
Copy link
Contributor Author

@swift-ci please smoke test

Copy link
Contributor

@zoecarver zoecarver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you Egor!

@egorzhdan
Copy link
Contributor Author

@swift-ci please smoke test Windows platform

@egorzhdan
Copy link
Contributor Author

@swift-ci please test Windows platform

@egorzhdan
Copy link
Contributor Author

@swift-ci please smoke test Windows platform

@egorzhdan
Copy link
Contributor Author

@swift-ci please test Windows platform

@egorzhdan egorzhdan force-pushed the egorzhdan/cxx-template-linker-error branch from ab9f2fe to 74442e8 Compare April 7, 2022 18:01
@egorzhdan
Copy link
Contributor Author

@swift-ci please smoke test

@egorzhdan
Copy link
Contributor Author

@swift-ci please smoke test Windows

…t modules

If a templated C++ class is used from two different C++ modules, and those modules are included in Swift, Clang will create different two different redecls for the class & its methods.

For each of the methods, only one of the redecls would actually have a body, the other would have empty bodies. That prevents `ClangDeclFinder` from properly finding the symbols referenced from a method body, leading to a linker error in some cases, when the first redecl is missing a body.

This prevents `std::string` from being used on Linux:
```
/tmp/use-std-string-2dd593.o:use-std-string-2dd593.o:function void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag): error: undefined reference to 'bool __gnu_cxx::__is_null_pointer<char>(char*)'
/tmp/use-std-string-2dd593.o:use-std-string-2dd593.o:function void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag): error: undefined reference to 'std::iterator_traits<char*>::difference_type std::distance<char*>(char*, char*)'
clang-13: error: linker command failed with exit code 1 (use -v to see invocation)
<unknown>:0: error: link command failed with exit code 1 (use -v to see invocation)
```
@egorzhdan egorzhdan force-pushed the egorzhdan/cxx-template-linker-error branch from 74442e8 to e9b0c8d Compare April 7, 2022 19:31
@egorzhdan
Copy link
Contributor Author

@swift-ci please smoke test

@egorzhdan
Copy link
Contributor Author

@swift-ci please smoke test Windows

@egorzhdan egorzhdan merged commit 27ad938 into main Apr 7, 2022
@egorzhdan egorzhdan deleted the egorzhdan/cxx-template-linker-error branch April 7, 2022 21:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ interop Feature: Interoperability with C++
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants