diff options
author | Serge Pavlov <sepavloff@gmail.com> | 2017-06-08 06:07:07 +0000 |
---|---|---|
committer | Serge Pavlov <sepavloff@gmail.com> | 2017-06-08 06:07:07 +0000 |
commit | 673f44c769ee85e592a8e00d77a6ce4231edf1dc (patch) | |
tree | 7f19bc65c1c74591519e96f470cbe1344381ab1e /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 0c64e27207564763a588b743646b7cefa727e113 (diff) | |
download | bcm5719-llvm-673f44c769ee85e592a8e00d77a6ce4231edf1dc.tar.gz bcm5719-llvm-673f44c769ee85e592a8e00d77a6ce4231edf1dc.zip |
Improve diagnostics if friend function redefines file-level function.
Clang makes check for function redefinition after it merged the new
declaration with the existing one. As a result, it produces poor
diagnostics in the case of a friend function defined inline, as in
the code:
```
void func() {}
class C { friend void func() {} };
```
Error message in this case states that `inline declaration of 'func'
follows non-inline definition`, which is misleading, as `func` does
not have explicit `inline` specifier.
With this changes compiler reports function redefinition if the new
function is a friend defined inline and it does not have explicit
`inline` specifier.
Differential Revision: https://reviews.llvm.org/D26065
llvm-svn: 304964
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 3e2306361cd..313552e23bc 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -638,7 +638,12 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Diag(Old->getLocation(), diag::note_previous_declaration); Invalid = true; } else if (!Old->getMostRecentDecl()->isInlined() && New->isInlined() && - Old->isDefined(Def)) { + Old->isDefined(Def) && + // If a friend function is inlined but does not have 'inline' + // specifier, it is a definition. Do not report attribute conflict + // in this case, redefinition will be diagnosed later. + (New->isInlineSpecified() || + New->getFriendObjectKind() == Decl::FOK_None)) { // 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. |