Skip to content

Commit 8b4821f

Browse files
authored
[cxx-interop] Fix test header to declare linkage for a implicit template (#72522)
The header was defining a function, the function created a lambda, and the lambda was transformed into a `std::function`. This transformation is incorrect because the function scope does not have linkage, so the instantiated types will not have linkage either, causing the error below. ``` .../include/c++/11.2.0/bits/invoke.h:104:5: error: function 'std::__invoke_r<int, (lambda at .../swift/test/Interop/Cxx/stdlib/Inputs/std-function.h:9:10) &, int>' is used but not defined in this translation unit, and cannot be defined in any other translation unit because its type does not have linkage 102 │ template<typename _Res, typename _Callable, typename... _Args> 103 │ constexpr enable_if_t<is_invocable_r_v<_Res, _Callable, _Args...>, _Res> 104 │ __invoke_r(_Callable&& __fn, _Args&&... __args) │ ╰─ error: function 'std::__invoke_r<int, (lambda at .../swift/test/Interop/Cxx/stdlib/Inputs/std-function.h:9:10) &, int>' is used but not defined in this translation unit, and cannot be defined in any other translation unit because its type does not have linkage 105 │ noexcept(is_nothrow_invocable_r_v<_Res, _Callable, _Args...>) 106 │ { } ``` Declaring the function `inline` forces each TU to have their own copies of the function, which avoids the instantiated templates from being in a different TU than the one using them. The header would not have worked in a normal C++ program, since none of the functions declare linkage, they would have been defined in each TU that included the header and it would fail linking as soon as two of those TU tried to be linked together. Declaring the functions `inline` avoids the problem (a more normal header, only with declarations, would also worked).
1 parent 6132386 commit 8b4821f

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

test/Interop/Cxx/stdlib/Inputs/std-function.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55

66
using FunctionIntToInt = std::function<int(int)>;
77

8-
FunctionIntToInt getIdentityFunction() {
8+
inline FunctionIntToInt getIdentityFunction() {
99
return [](int x) { return x; };
1010
}
1111

12-
bool isEmptyFunction(FunctionIntToInt f) { return !(bool)f; }
12+
inline bool isEmptyFunction(FunctionIntToInt f) { return !(bool)f; }
1313

14-
int invokeFunction(FunctionIntToInt f, int x) { return f(x); }
14+
inline int invokeFunction(FunctionIntToInt f, int x) { return f(x); }
1515

1616
#endif // TEST_INTEROP_CXX_STDLIB_INPUTS_STD_FUNCTION_H

0 commit comments

Comments
 (0)