diff options
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 3 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/friend.cpp | 16 |
2 files changed, 18 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7b2848bf606..b0e6acaedb9 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -615,7 +615,8 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, << New << New->isConstexpr(); Diag(Old->getLocation(), diag::note_previous_declaration); Invalid = true; - } else if (!Old->isInlined() && New->isInlined() && Old->isDefined(Def)) { + } else if (!Old->getMostRecentDecl()->isInlined() && New->isInlined() && + Old->isDefined(Def)) { // C++11 [dcl.fcn.spec]p4: // If the definition of a function appears in a translation unit before its // first declaration as inline, the program is ill-formed. diff --git a/clang/test/SemaTemplate/friend.cpp b/clang/test/SemaTemplate/friend.cpp index e78a067ef8f..ef1aed50e62 100644 --- a/clang/test/SemaTemplate/friend.cpp +++ b/clang/test/SemaTemplate/friend.cpp @@ -31,3 +31,19 @@ namespace PR6770 { friend class f1; // expected-error{{'friend' used outside of class}} } } + +namespace friend_redecl_inline { +// We had a bug where instantiating the foo friend declaration would check the +// defined-ness of the most recent decl while checking if the canonical decl was +// inlined. +void foo(); +void bar(); +template <typename T> +class C { + friend void foo(); + friend inline void bar(); +}; +inline void foo() {} +inline void bar() {} +C<int> c; +} |

