summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-08-25 02:10:01 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-08-25 02:10:01 +0000
commit88126a25ebae096fa45b83b2998657c0c9030449 (patch)
tree2dd494a04781ffdf4b3898ce56bdd669837b33f3
parent6e69927d03eddf49f83c03a0eea1a93be085d52b (diff)
downloadbcm5719-llvm-88126a25ebae096fa45b83b2998657c0c9030449.tar.gz
bcm5719-llvm-88126a25ebae096fa45b83b2998657c0c9030449.zip
[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
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp4
-rw-r--r--clang/test/Modules/Inputs/odr/a.h6
-rw-r--r--clang/test/Modules/Inputs/odr/b.h8
-rw-r--r--clang/test/Modules/odr.cpp3
4 files changed, 19 insertions, 2 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 3ac67071f0d..4f1c4ec6915 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/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/clang/test/Modules/Inputs/odr/a.h b/clang/test/Modules/Inputs/odr/a.h
index 26144b86e8d..5a3f5240948 100644
--- a/clang/test/Modules/Inputs/odr/a.h
+++ b/clang/test/Modules/Inputs/odr/a.h
@@ -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;
}
diff --git a/clang/test/Modules/Inputs/odr/b.h b/clang/test/Modules/Inputs/odr/b.h
index b4063979474..a4a693df2bf 100644
--- a/clang/test/Modules/Inputs/odr/b.h
+++ b/clang/test/Modules/Inputs/odr/b.h
@@ -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});
}
diff --git a/clang/test/Modules/odr.cpp b/clang/test/Modules/odr.cpp
index 5ab10d2ce41..120ca20e0a8 100644
--- a/clang/test/Modules/odr.cpp
+++ b/clang/test/Modules/odr.cpp
@@ -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.
OpenPOWER on IntegriCloud