<div dir="ltr">On Tue, Jun 25, 2013 at 1:30 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class=""><div class="h5">On Tue, Jun 25, 2013 at 12:59 AM, David Majnemer<br>

<<a href="mailto:david.majnemer@gmail.com">david.majnemer@gmail.com</a>> wrote:<br>
> The attached patch implements DR136 [*], "Default arguments and friend<br>
> functions."<br>
><br>
> The crux of this issue is that a function declaration that specifies a<br>
> default argument must define the function and be it's only declaration.<br>
><br>
> [*] <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#136" target="_blank">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#136</a><br>
<br>
</div></div>--- lib/Sema/SemaDeclCXX.cpp    (revision 184825)<br>
+++ lib/Sema/SemaDeclCXX.cpp    (working copy)<br>
@@ -404,6 +404,15 @@<br>
   }<br>
 }<br>
<br>
+static bool functionDeclHasDefaultArgument(const FunctionDecl *FD) {<br>
+  for (unsigned NumParams = FD->getNumParams(); NumParams > 0; --NumParams) {<br>
+    const ParmVarDecl *PVD = FD->getParamDecl(NumParams-1);<br>
+    if (PVD->hasDefaultArg() && !PVD->hasInheritedDefaultArg())<br>
+      return true;<br>
+  }<br>
<br>
You can bail out early if you hit a parameter that doesn't have a<br>
default argument (since no earlier parameters can have a default<br>
argument).<br></blockquote><div><br></div><div style>Great point, implemented.</div><div style><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<br>
<br>
@@ -578,6 +587,18 @@<br>
     Invalid = true;<br>
   }<br>
<br>
+  // C++11 [dcl.fct.default]p4: If a friend declaration specifies a default<br>
+  // argument expression, that declaration shall be a definition and shall be<br>
+  // the only declaration of the function or function template in the<br>
+  // translation unit.<br>
+  if (!isa<CXXMethodDecl>(Old) &&<br>
<br>
What is this check for?<br></blockquote><div><br></div><div style>See bellow.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<br>
<br>
+      Old->getFriendObjectKind() == Decl::FOK_Undeclared &&<br>
+      functionDeclHasDefaultArgument(Old)) {<br>
+      Diag(New->getLocation(), diag::err_friend_decl_with_def_arg_redeclared);<br>
+      Diag(Old->getLocation(), diag::note_previous_declaration);<br>
+      Invalid = true;<br>
+    }<br>
<br>
Too much indentation for these 4 lines.<br></blockquote><div><br></div><div style>Fixed.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<br>
<br>
@@ -11377,6 +11398,18 @@<br>
     else<br>
       FD = cast<FunctionDecl>(ND);<br>
<br>
+    // C++11 [dcl.fct.default]p4: If a friend declaration specifies a<br>
+    // default argument expression, that declaration shall be a definition<br>
+    // and shall be the only declaration of the function or function<br>
+    // template in the translation unit.<br>
+    if (!isa<CXXMethodDecl>(FD) && functionDeclHasDefaultArgument(FD)) {<br>
<br>
This isa check looks suspicious. Doesn't it lead to us incorrectly<br>
accepting this:<br>
<br>
  struct A { void f(int); };<br>
  struct B { friend void A::f(int = 0); };<br>
<br>
?<br>
</blockquote></div><br></div><div class="gmail_extra" style>The short and boring story is that I added this check while investigating the crash in PR16423.</div><div class="gmail_extra" style>Sorry for letting it split into the patch :/</div>
<div class="gmail_extra" style><br></div><div class="gmail_extra" style>-- </div><div class="gmail_extra" style>David Majnemer</div><div class="gmail_extra"><br></div></div>