diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 313552e23bc8b2e95050fc75261b52de17b8a053..844299bb87cf1a0ab7d302b63b7e667b2236a117 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. diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp index a5ac85cb6f3a314ef1cafd25a2add38cde800fd7..6014268a18601078c54a608b7f19e961861ad7e0 100644 --- a/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp +++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp @@ -73,3 +73,36 @@ void Test () } } // namespace + +namespace pr12724 { + +void func_01(bool param = true); +class C01 { +public: + friend void func_01(bool param); +}; + +void func_02(bool param = true); +template<typename T> +class C02 { +public: + friend void func_02(bool param); +}; +C02<int> c02; + +void func_03(bool param); +template<typename T> +class C03 { +public: + friend void func_03(bool param); +}; +void func_03(bool param = true); +C03<int> c03; + +void main() { + func_01(); + func_02(); + func_03(); +} + +} // namespace pr12724