diff options
author | Richard Trieu <rtrieu@google.com> | 2018-02-22 05:50:29 +0000 |
---|---|---|
committer | Richard Trieu <rtrieu@google.com> | 2018-02-22 05:50:29 +0000 |
commit | 0ac2eb7369f8acb6c7c5485299abc66cdcca04b0 (patch) | |
tree | 61e85225a96ef733e7a5feb1afbb081a6f3779f4 /clang | |
parent | f65efae5c45bdccddb40b829cf28fcbf70af891b (diff) | |
download | bcm5719-llvm-0ac2eb7369f8acb6c7c5485299abc66cdcca04b0.tar.gz bcm5719-llvm-0ac2eb7369f8acb6c7c5485299abc66cdcca04b0.zip |
[ODRHash] Fix hashing for friend functions.
When hashing a templated function, use the hash of the function it was
instantiated from.
llvm-svn: 325742
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/ODRHash.cpp | 3 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/odr_hash-Friend/Bad.h | 17 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/odr_hash-Friend/Good.h | 17 | ||||
-rw-r--r-- | clang/test/Modules/Inputs/odr_hash-Friend/module.modulemap | 8 | ||||
-rw-r--r-- | clang/test/Modules/odr_hash-Friend.cpp | 76 |
6 files changed, 120 insertions, 7 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 30599ea7cfb..c4da87c013d 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3625,6 +3625,12 @@ unsigned FunctionDecl::getODRHash() { } } + if (auto *FT = getInstantiatedFromMemberFunction()) { + HasODRHash = true; + ODRHash = FT->getODRHash(); + return ODRHash; + } + class ODRHash Hash; Hash.AddFunctionDecl(this); HasODRHash = true; diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 4104d3454e5..528e32aaba2 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -484,9 +484,6 @@ void ODRHash::AddFunctionDecl(const FunctionDecl *Function) { if (!Function->hasBody()) return; if (!Function->getBody()) return; - // TODO: Fix hashing friend functions. - if (Function->getFriendObjectKind()) return; - // Skip functions that are specializations or in specialization context. const DeclContext *DC = Function; while (DC) { diff --git a/clang/test/Modules/Inputs/odr_hash-Friend/Bad.h b/clang/test/Modules/Inputs/odr_hash-Friend/Bad.h new file mode 100644 index 00000000000..c0a6d1f9889 --- /dev/null +++ b/clang/test/Modules/Inputs/odr_hash-Friend/Bad.h @@ -0,0 +1,17 @@ +template <class T> +struct iterator { + void Compare(const iterator &x) { return; } + friend void Check(iterator) { return; } +}; + +template <class T = int> struct Box { + iterator<T> I; + + void test() { + Check(I); + I.Compare(I); + } +}; + +// Force instantiation of Box<int> +Box<> B; diff --git a/clang/test/Modules/Inputs/odr_hash-Friend/Good.h b/clang/test/Modules/Inputs/odr_hash-Friend/Good.h new file mode 100644 index 00000000000..4c38392eb6e --- /dev/null +++ b/clang/test/Modules/Inputs/odr_hash-Friend/Good.h @@ -0,0 +1,17 @@ +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); + } +}; + +// Force instantiation of Box<int> +Box<> B; diff --git a/clang/test/Modules/Inputs/odr_hash-Friend/module.modulemap b/clang/test/Modules/Inputs/odr_hash-Friend/module.modulemap index 28e1832e30e..449d51e7f70 100644 --- a/clang/test/Modules/Inputs/odr_hash-Friend/module.modulemap +++ b/clang/test/Modules/Inputs/odr_hash-Friend/module.modulemap @@ -13,3 +13,11 @@ module Module2 { module Module3 { header "M3.h" } + +module Good { + header "Good.h" +} + +module Bad { + header "Bad.h" +} diff --git a/clang/test/Modules/odr_hash-Friend.cpp b/clang/test/Modules/odr_hash-Friend.cpp index 39c0c4b762c..8a2513e2f9c 100644 --- a/clang/test/Modules/odr_hash-Friend.cpp +++ b/clang/test/Modules/odr_hash-Friend.cpp @@ -1,21 +1,89 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t/modules.cache \ +// PR35939: MicrosoftMangle.cpp triggers an assertion failure on this test. +// UNSUPPORTED: system-windows + +// RUN: %clang_cc1 \ // 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 +// RUN: -std=c++11 -x c++ %s -verify -DTEST1 -fcolor-diagnostics -// PR35939: MicrosoftMangle.cpp triggers an assertion failure on this test. -// UNSUPPORTED: system-windows +// RUN: %clang_cc1 \ +// 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 -DTEST2 -fcolor-diagnostics + +// RUN: %clang_cc1 \ +// 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 -DTEST3 -fcolor-diagnostics + +// RUN: %clang_cc1 \ +// 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 -DTEST3 -fcolor-diagnostics + +// RUN: %clang_cc1 \ +// 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 -DTEST3 -fcolor-diagnostics +#if defined(TEST1) +#include "Box.h" +#include "M1.h" +#include "M3.h" // expected-no-diagnostics +#endif +#if defined(TEST2) #include "Box.h" #include "M1.h" #include "M3.h" +#include "Good.h" +// expected-no-diagnostics +#endif + +#if defined(TEST3) +#include "Good.h" +#include "Box.h" +#include "M1.h" +#include "M3.h" +// expected-no-diagnostics +#endif + +#if defined(TEST4) +#include "Box.h" +#include "M1.h" +#include "M3.h" +#include "Bad.h" +// expected-error@Bad.h:* {{'Check' has different definitions in different modules; definition in module 'Bad' first difference is function body}} +// expected-note@Box.h:* {{but in 'Box' found a different body}} +#endif + +#if defined(TEST5) +#include "Bad.h" +#include "Box.h" +#include "M1.h" +#include "M3.h" +// expected-error@Bad.h:* {{'Check' has different definitions in different modules; definition in module 'Bad' first difference is function body}} +// expected-note@Box.h:* {{but in 'Box' found a different body}} +#endif + void Run() { Box<> Present; |