From: Richard Smith Date: Mon, 25 Aug 2014 02:10:01 +0000 (+0000) Subject: [modules] Fix false report of an ODR violation when merging friend X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5780abeb80ecef609c6465645304a5221dd765d7;p=clang [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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216369 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 3ac67071f0..4f1c4ec691 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -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); diff --git a/test/Modules/Inputs/odr/a.h b/test/Modules/Inputs/odr/a.h index 26144b86e8..5a3f524094 100644 --- a/test/Modules/Inputs/odr/a.h +++ b/test/Modules/Inputs/odr/a.h @@ -8,6 +8,12 @@ struct X { int n; } x1; +template +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; } diff --git a/test/Modules/Inputs/odr/b.h b/test/Modules/Inputs/odr/b.h index b406397947..a4a693df2b 100644 --- a/test/Modules/Inputs/odr/b.h +++ b/test/Modules/Inputs/odr/b.h @@ -4,6 +4,12 @@ struct Y { } y2; enum E { e2 }; +template +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{0} == F{1}); } diff --git a/test/Modules/odr.cpp b/test/Modules/odr.cpp index 5ab10d2ce4..120ca20e0a 100644 --- a/test/Modules/odr.cpp +++ b/test/Modules/odr.cpp @@ -6,6 +6,9 @@ struct X { // expected-note {{definition has no member 'n'}} }; @import a; + +bool b = F{0} == F{1}; + @import b; // Trigger the declarations from a and b to be imported.