PBEnd = PendingBodies.end();
PB != PBEnd; ++PB) {
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(PB->first)) {
+ // For a function defined inline within a class template, force the
+ // canonical definition to be the one inside the canonical definition of
+ // the template. This ensures that we instantiate from a correct view
+ // of the template.
+ //
+ // Sadly we can't do this more generally: we can't be sure that all
+ // copies of an arbitrary class definition will have the same members
+ // defined (eg, some member functions may not be instantiated, and some
+ // special members may or may not have been implicitly defined).
+ if (auto *RD = dyn_cast<CXXRecordDecl>(FD->getLexicalParent()))
+ if (RD->isDependentContext() && !RD->isThisDeclarationADefinition())
+ continue;
+
// FIXME: Check for =delete/=default?
// FIXME: Complain about ODR violations here?
const FunctionDecl *Defn = nullptr;
--- /dev/null
+// RUN: %clang_cc1 -fmodules %s -verify
+// 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();
+}