
merged function definitions; also merge functions with deduced return types. This seems like two independent fixes, but unfortunately they are hard to separate because it's challenging to reliably test either one of them without also testing the other. A complication arises with deduced return type support: we need the type of the function in order to know how to merge it, but we can't load the actual type of the function because it might reference an entity declared within the function (and we need to have already merged the function to correctly merge that entity, which we would need to do to determine if the function types match). So we instead compare the declared function type when merging functions, and defer loading the actual type of a function with a deduced type until we've finished loading and merging the function. This reverts r336175, reinstating r336021, with one change (for PR38015): we look at the TypeSourceInfo of the first-so-far declaration of each function when considering whether to merge two functions. This works around a problem where the calling convention in the TypeSourceInfo for subsequent redeclarations may not match if it was implicitly adjusted. llvm-svn: 336240
36 lines
1.2 KiB
C++
36 lines
1.2 KiB
C++
// RUN: %clang_cc1 -fmodules %s -verify
|
|
// RUN: %clang_cc1 -fmodules %s -verify -triple i686-windows
|
|
// expected-no-diagnostics
|
|
#pragma clang module build A
|
|
module A {}
|
|
#pragma clang module contents
|
|
#pragma clang module begin A
|
|
template<typename T> struct ct { friend auto operator-(ct, ct) { struct X {}; return X(); } void x(); };
|
|
#pragma clang module end
|
|
#pragma clang module endbuild
|
|
|
|
#pragma clang module build B
|
|
module B {}
|
|
#pragma clang module contents
|
|
#pragma clang module begin B
|
|
template<typename T> struct ct { friend auto operator-(ct, ct) { struct X{}; return X(); } void x(); };
|
|
inline auto f() { return ct<float>() - ct<float>(); }
|
|
#pragma clang module end
|
|
#pragma clang module endbuild
|
|
|
|
// Force the definition of ct in module A to be the primary definition.
|
|
#pragma clang module import A
|
|
template<typename T> void ct<T>::x() {}
|
|
|
|
// Attempt to cause the definition of operator- in the ct primary template in
|
|
// module B to be the primary definition of that function. If that happens,
|
|
// we'll be left with a class template ct that appears to not contain a
|
|
// definition of the inline friend function.
|
|
#pragma clang module import B
|
|
auto v = f();
|
|
|
|
ct<int> make();
|
|
void h() {
|
|
make() - make();
|
|
}
|