[PATCH] Implement DR136
Richard Smith
richard at metafoo.co.uk
Tue Jun 25 13:30:07 PDT 2013
On Tue, Jun 25, 2013 at 12:59 AM, David Majnemer
<david.majnemer at gmail.com> wrote:
> The attached patch implements DR136 [*], "Default arguments and friend
> functions."
>
> The crux of this issue is that a function declaration that specifies a
> default argument must define the function and be it's only declaration.
>
> [*] http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#136
--- lib/Sema/SemaDeclCXX.cpp (revision 184825)
+++ lib/Sema/SemaDeclCXX.cpp (working copy)
@@ -404,6 +404,15 @@
}
}
+static bool functionDeclHasDefaultArgument(const FunctionDecl *FD) {
+ for (unsigned NumParams = FD->getNumParams(); NumParams > 0; --NumParams) {
+ const ParmVarDecl *PVD = FD->getParamDecl(NumParams-1);
+ if (PVD->hasDefaultArg() && !PVD->hasInheritedDefaultArg())
+ return true;
+ }
You can bail out early if you hit a parameter that doesn't have a
default argument (since no earlier parameters can have a default
argument).
@@ -578,6 +587,18 @@
Invalid = true;
}
+ // C++11 [dcl.fct.default]p4: If a friend declaration specifies a default
+ // argument expression, that declaration shall be a deļ¬nition and shall be
+ // the only declaration of the function or function template in the
+ // translation unit.
+ if (!isa<CXXMethodDecl>(Old) &&
What is this check for?
+ Old->getFriendObjectKind() == Decl::FOK_Undeclared &&
+ functionDeclHasDefaultArgument(Old)) {
+ Diag(New->getLocation(), diag::err_friend_decl_with_def_arg_redeclared);
+ Diag(Old->getLocation(), diag::note_previous_declaration);
+ Invalid = true;
+ }
Too much indentation for these 4 lines.
@@ -11377,6 +11398,18 @@
else
FD = cast<FunctionDecl>(ND);
+ // C++11 [dcl.fct.default]p4: If a friend declaration specifies a
+ // default argument expression, that declaration shall be a definition
+ // and shall be the only declaration of the function or function
+ // template in the translation unit.
+ if (!isa<CXXMethodDecl>(FD) && functionDeclHasDefaultArgument(FD)) {
This isa check looks suspicious. Doesn't it lead to us incorrectly
accepting this:
struct A { void f(int); };
struct B { friend void A::f(int = 0); };
?
More information about the cfe-commits
mailing list