[modules] Fix false report of an ODR violation when merging friend

declarations. We can't expect to find them in the canonical definition
of the class, because that's not where they live.

This means we no longer reject real ODR violations with friend declarations,
but we weren't consistently doing so anyway.

llvm-svn: 216369
This commit is contained in:
Richard Smith 2014-08-25 02:10:01 +00:00
parent 6e69927d03
commit 88126a25eb
4 changed files with 19 additions and 2 deletions

View File

@ -2548,7 +2548,9 @@ ASTDeclReader::FindExistingResult ASTDeclReader::findExisting(NamedDecl *D) {
//
// FIXME: We should do something similar if we merge two definitions of the
// same template specialization into the same CXXRecordDecl.
if (Reader.MergedDeclContexts.count(D->getLexicalDeclContext()))
auto MergedDCIt = Reader.MergedDeclContexts.find(D->getLexicalDeclContext());
if (MergedDCIt != Reader.MergedDeclContexts.end() &&
MergedDCIt->second == D->getDeclContext())
Reader.PendingOdrMergeChecks.push_back(D);
return FindExistingResult(Reader, D, /*Existing=*/nullptr);

View File

@ -8,6 +8,12 @@ struct X {
int n;
} x1;
template<typename T>
struct F {
int n;
friend bool operator==(const F &a, const F &b) { return a.n == b.n; }
};
int f() {
return y1.n + e1 + y1.f + x1.n;
}

View File

@ -4,6 +4,12 @@ struct Y {
} y2;
enum E { e2 };
template<typename T>
struct F {
int n;
friend bool operator==(const F &a, const F &b) { return a.n == b.n; }
};
int g() {
return y2.m + e2 + y2.f;
return y2.m + e2 + y2.f + (F<int>{0} == F<int>{1});
}

View File

@ -6,6 +6,9 @@ struct X { // expected-note {{definition has no member 'n'}}
};
@import a;
bool b = F<int>{0} == F<int>{1};
@import b;
// Trigger the declarations from a and b to be imported.