[PATCH] D30393: Do not inherit default arguments for friend function in class template.

Serge Pavlov via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 5 22:58:09 PDT 2017


sepavloff updated this revision to Diff 101512.
sepavloff added a comment.

Rebased patch


https://reviews.llvm.org/D30393

Files:
  lib/Sema/SemaDeclCXX.cpp
  test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp


Index: test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp
===================================================================
--- test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp
+++ test/CXX/dcl.decl/dcl.meaning/dcl.fct.default/p4.cpp
@@ -73,3 +73,36 @@
 }
 
 } // 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
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -547,17 +547,23 @@
       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.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D30393.101512.patch
Type: text/x-patch
Size: 2782 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170606/abe4fe17/attachment-0001.bin>


More information about the cfe-commits mailing list