]> granicus.if.org Git - clang/commitdiff
[modules] Fix false report of an ODR violation when merging friend
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 25 Aug 2014 02:10:01 +0000 (02:10 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 25 Aug 2014 02:10:01 +0000 (02:10 +0000)
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

lib/Serialization/ASTReaderDecl.cpp
test/Modules/Inputs/odr/a.h
test/Modules/Inputs/odr/b.h
test/Modules/odr.cpp

index 3ac67071f0d2ec74f0ac7353266512562eb703a6..4f1c4ec69158db5bcc4a5ef331b8e0fa75d4a25c 100644 (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);
index 26144b86e8d1f620b22af74cd5e771b60684ba5f..5a3f52409486ea577890016f9d1206ea319a8b80 100644 (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;
 }
index b4063979474f6aa083925c946d0534d0d618cb45..a4a693df2bf1cd8dae893522ab8f35b41747cf97 100644 (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});
 }
index 5ab10d2ce41900f9819eb250a60ce4806776aad5..120ca20e0a873eccd972f6dad7d042b8da247921 100644 (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.