]> granicus.if.org Git - clang/commitdiff
[ODRHash] Don't hash friend functions.
authorRichard Trieu <rtrieu@google.com>
Fri, 12 Jan 2018 04:42:27 +0000 (04:42 +0000)
committerRichard Trieu <rtrieu@google.com>
Fri, 12 Jan 2018 04:42:27 +0000 (04:42 +0000)
In certain combinations of templated classes and friend functions, the body
of friend functions does not get propagated along with function signature.
Exclude friend functions for hashing to avoid this case.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@322350 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ODRHash.cpp
test/Modules/Inputs/odr_hash-Friend/Box.h [new file with mode: 0644]
test/Modules/Inputs/odr_hash-Friend/M1.h [new file with mode: 0644]
test/Modules/Inputs/odr_hash-Friend/M2.h [new file with mode: 0644]
test/Modules/Inputs/odr_hash-Friend/M3.h [new file with mode: 0644]
test/Modules/Inputs/odr_hash-Friend/module.modulemap [new file with mode: 0644]
test/Modules/odr_hash-Friend.cpp [new file with mode: 0644]

index 088d8bedd453b9422f4caf0bb51dfa8f9fca6bc1..38e8d34135f9be45f18c1342466295778d363018 100644 (file)
@@ -478,6 +478,8 @@ void ODRHash::AddFunctionDecl(const FunctionDecl *Function) {
 
   // TODO: Fix hashing for class methods.
   if (isa<CXXMethodDecl>(Function)) return;
+  // And friend functions.
+  if (Function->getFriendObjectKind()) return;
 
   // Skip functions that are specializations or in specialization context.
   const DeclContext *DC = Function;
diff --git a/test/Modules/Inputs/odr_hash-Friend/Box.h b/test/Modules/Inputs/odr_hash-Friend/Box.h
new file mode 100644 (file)
index 0000000..01ab90d
--- /dev/null
@@ -0,0 +1,14 @@
+template <class T>
+struct iterator {
+  void Compare(const iterator &x) { }
+  friend void Check(iterator) {}
+};
+
+template <class T = int> struct Box {
+  iterator<T> I;
+
+  void test() {
+    Check(I);
+    I.Compare(I);
+  }
+};
diff --git a/test/Modules/Inputs/odr_hash-Friend/M1.h b/test/Modules/Inputs/odr_hash-Friend/M1.h
new file mode 100644 (file)
index 0000000..202ad06
--- /dev/null
@@ -0,0 +1,6 @@
+#include "Box.h"
+
+void Peek() {
+  Box<> Gift;
+  Gift.test();
+}
diff --git a/test/Modules/Inputs/odr_hash-Friend/M2.h b/test/Modules/Inputs/odr_hash-Friend/M2.h
new file mode 100644 (file)
index 0000000..69f08a9
--- /dev/null
@@ -0,0 +1,5 @@
+#include "Box.h"
+void x() {
+  Box<> Unused;
+  //Unused.test();
+}
diff --git a/test/Modules/Inputs/odr_hash-Friend/M3.h b/test/Modules/Inputs/odr_hash-Friend/M3.h
new file mode 100644 (file)
index 0000000..ab457e0
--- /dev/null
@@ -0,0 +1,7 @@
+#include "Box.h"
+#include "M2.h"
+
+void Party() {
+  Box<> Present;
+  Present.test();
+}
diff --git a/test/Modules/Inputs/odr_hash-Friend/module.modulemap b/test/Modules/Inputs/odr_hash-Friend/module.modulemap
new file mode 100644 (file)
index 0000000..28e1832
--- /dev/null
@@ -0,0 +1,15 @@
+module Box {
+  header "Box.h"
+}
+
+module Module1 {
+  header "M1.h"
+}
+
+module Module2 {
+  header "M2.h"
+}
+
+module Module3 {
+  header "M3.h"
+}
diff --git a/test/Modules/odr_hash-Friend.cpp b/test/Modules/odr_hash-Friend.cpp
new file mode 100644 (file)
index 0000000..408e7f3
--- /dev/null
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t
+
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/modules.cache \
+// RUN:  -I %S/Inputs/odr_hash-Friend \
+// RUN:  -emit-obj -o /dev/null \
+// RUN:  -fmodules \
+// RUN:  -fimplicit-module-maps \
+// RUN:  -fmodules-cache-path=%t/modules.cache \
+// RUN:  -std=c++11 -x c++ %s -verify
+
+// expected-no-diagnostics
+
+#include "Box.h"
+#include "M1.h"
+#include "M3.h"
+
+void Run() {
+  Box<> Present;
+}