summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorSerge Pavlov <sepavloff@gmail.com>2017-06-08 06:31:19 +0000
committerSerge Pavlov <sepavloff@gmail.com>2017-06-08 06:31:19 +0000
commitff4214ddcfab9fd92c15cc01c9c2e17a8f6217ad (patch)
treeb0321360528a81c7305019fb8d1f1d145c6dd4a5 /lib/Sema/SemaDeclCXX.cpp
parent14318c6aa40d7c68c4341f43fbc3d0980f6d21a8 (diff)
Do not inherit default arguments for friend function in class template.
A function declared in a friend declaration may have declarations prior to the containing class definition. If such declaration defines default argument, the friend function declaration inherits them. This behavior causes problems if the class where the friend is declared is a template: during the class instantiation the friend function looks like if it had default arguments, so error is triggered. With this change friend functions declared in class templates do not inherit default arguments. Actual set of them will be defined at the point where the containing class is instantiated. This change fixes PR12724. Differential Revision: https://reviews.llvm.org/D30393 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@304965 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp28
1 files changed, 17 insertions, 11 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 313552e23b..844299bb87 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -547,17 +547,23 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old,
Diag(OldParam->getLocation(), diag::note_previous_definition)
<< OldParam->getDefaultArgRange();
} else if (OldParamHasDfl) {
- // Merge the old default argument into the new parameter.
- // It's important to use getInit() here; getDefaultArg()
- // strips off any top-level ExprWithCleanups.
- NewParam->setHasInheritedDefaultArg();
- if (OldParam->hasUnparsedDefaultArg())
- NewParam->setUnparsedDefaultArg();
- else if (OldParam->hasUninstantiatedDefaultArg())
- NewParam->setUninstantiatedDefaultArg(
- OldParam->getUninstantiatedDefaultArg());
- else
- NewParam->setDefaultArg(OldParam->getInit());
+ // Merge the old default argument into the new parameter unless the new
+ // function is a friend declaration in a template class. In the latter
+ // case the default arguments will be inherited when the friend
+ // declaration will be instantiated.
+ if (New->getFriendObjectKind() == Decl::FOK_None ||
+ !New->getLexicalDeclContext()->isDependentContext()) {
+ // It's important to use getInit() here; getDefaultArg()
+ // strips off any top-level ExprWithCleanups.
+ NewParam->setHasInheritedDefaultArg();
+ if (OldParam->hasUnparsedDefaultArg())
+ NewParam->setUnparsedDefaultArg();
+ else if (OldParam->hasUninstantiatedDefaultArg())
+ NewParam->setUninstantiatedDefaultArg(
+ OldParam->getUninstantiatedDefaultArg());
+ else
+ NewParam->setDefaultArg(OldParam->getInit());
+ }
} else if (NewParamHasDfl) {
if (New->getDescribedFunctionTemplate()) {
// Paragraph 4, quoted above, only applies to non-template functions.