From 4eefb4511de5dccb95cd5e3e43340503f5259e31 Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Fri, 12 Jan 2018 04:42:27 +0000 Subject: [PATCH] [ODRHash] Don't hash friend functions. 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. llvm-svn: 322350 --- clang/lib/AST/ODRHash.cpp | 2 ++ .../test/Modules/Inputs/odr_hash-Friend/Box.h | 14 ++++++++++++++ .../test/Modules/Inputs/odr_hash-Friend/M1.h | 6 ++++++ .../test/Modules/Inputs/odr_hash-Friend/M2.h | 5 +++++ .../test/Modules/Inputs/odr_hash-Friend/M3.h | 7 +++++++ .../Inputs/odr_hash-Friend/module.modulemap | 15 +++++++++++++++ clang/test/Modules/odr_hash-Friend.cpp | 19 +++++++++++++++++++ 7 files changed, 68 insertions(+) create mode 100644 clang/test/Modules/Inputs/odr_hash-Friend/Box.h create mode 100644 clang/test/Modules/Inputs/odr_hash-Friend/M1.h create mode 100644 clang/test/Modules/Inputs/odr_hash-Friend/M2.h create mode 100644 clang/test/Modules/Inputs/odr_hash-Friend/M3.h create mode 100644 clang/test/Modules/Inputs/odr_hash-Friend/module.modulemap create mode 100644 clang/test/Modules/odr_hash-Friend.cpp diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 088d8bedd453..38e8d34135f9 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -478,6 +478,8 @@ void ODRHash::AddFunctionDecl(const FunctionDecl *Function) { // TODO: Fix hashing for class methods. if (isa(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/clang/test/Modules/Inputs/odr_hash-Friend/Box.h b/clang/test/Modules/Inputs/odr_hash-Friend/Box.h new file mode 100644 index 000000000000..01ab90d601c2 --- /dev/null +++ b/clang/test/Modules/Inputs/odr_hash-Friend/Box.h @@ -0,0 +1,14 @@ +template +struct iterator { + void Compare(const iterator &x) { } + friend void Check(iterator) {} +}; + +template struct Box { + iterator I; + + void test() { + Check(I); + I.Compare(I); + } +}; diff --git a/clang/test/Modules/Inputs/odr_hash-Friend/M1.h b/clang/test/Modules/Inputs/odr_hash-Friend/M1.h new file mode 100644 index 000000000000..202ad06c3488 --- /dev/null +++ b/clang/test/Modules/Inputs/odr_hash-Friend/M1.h @@ -0,0 +1,6 @@ +#include "Box.h" + +void Peek() { + Box<> Gift; + Gift.test(); +} diff --git a/clang/test/Modules/Inputs/odr_hash-Friend/M2.h b/clang/test/Modules/Inputs/odr_hash-Friend/M2.h new file mode 100644 index 000000000000..69f08a957ede --- /dev/null +++ b/clang/test/Modules/Inputs/odr_hash-Friend/M2.h @@ -0,0 +1,5 @@ +#include "Box.h" +void x() { + Box<> Unused; + //Unused.test(); +} diff --git a/clang/test/Modules/Inputs/odr_hash-Friend/M3.h b/clang/test/Modules/Inputs/odr_hash-Friend/M3.h new file mode 100644 index 000000000000..ab457e0c08f2 --- /dev/null +++ b/clang/test/Modules/Inputs/odr_hash-Friend/M3.h @@ -0,0 +1,7 @@ +#include "Box.h" +#include "M2.h" + +void Party() { + Box<> Present; + Present.test(); +} diff --git a/clang/test/Modules/Inputs/odr_hash-Friend/module.modulemap b/clang/test/Modules/Inputs/odr_hash-Friend/module.modulemap new file mode 100644 index 000000000000..28e1832e30e9 --- /dev/null +++ b/clang/test/Modules/Inputs/odr_hash-Friend/module.modulemap @@ -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/clang/test/Modules/odr_hash-Friend.cpp b/clang/test/Modules/odr_hash-Friend.cpp new file mode 100644 index 000000000000..408e7f36b066 --- /dev/null +++ b/clang/test/Modules/odr_hash-Friend.cpp @@ -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; +}