<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I meant PR8748; test case fixed in r124863.<div><br></div><div><span class="Apple-tab-span" style="white-space:pre">      </span>- Doug</div><div><br><div><div>On Feb 3, 2011, at 9:59 PM, Nick Lewycky wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div class="gmail_quote">On 3 February 2011 20:20, Douglas Gregor <span dir="ltr"><<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

Author: dgregor<br>
Date: Thu Feb  3 22:20:44 2011<br>
New Revision: 124856<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=124856&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=124856&view=rev</a><br>
Log:<br>
Tighten up the semantics of default template arguments, per C++0x<br>
[temp.param]p9 and C++ DR226. Fixes PR8747.<br></blockquote><div><br></div><div>Hi Doug, I suspect this is the wrong PR#?</div><div><br></div><div>Nick</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">


<br>
Modified:<br>
    cfe/trunk/include/clang/Sema/Sema.h<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
    cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=124856&r1=124855&r2=124856&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=124856&r1=124855&r2=124856&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Feb  3 22:20:44 2011<br>
@@ -2914,7 +2914,8 @@<br>
     TPC_ClassTemplate,<br>
     TPC_FunctionTemplate,<br>
     TPC_ClassTemplateMember,<br>
-    TPC_FriendFunctionTemplate<br>
+    TPC_FriendFunctionTemplate,<br>
+    TPC_FriendFunctionTemplateDefinition<br>
   };<br>
<br>
   bool CheckTemplateParameterList(TemplateParameterList *NewParams,<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=124856&r1=124855&r2=124856&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=124856&r1=124855&r2=124856&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Feb  3 22:20:44 2011<br>
@@ -3967,8 +3967,14 @@<br>
       FunctionTemplateDecl *PrevTemplate = FunctionTemplate->getPreviousDeclaration();<br>
       CheckTemplateParameterList(FunctionTemplate->getTemplateParameters(),<br>
                                  PrevTemplate? PrevTemplate->getTemplateParameters() : 0,<br>
-                                 D.getDeclSpec().isFriendSpecified()? TPC_FriendFunctionTemplate<br>
-                                                  : TPC_FunctionTemplate);<br>
+                            D.getDeclSpec().isFriendSpecified()<br>
+                              ? (IsFunctionDefinition<br>
+                                   ? TPC_FriendFunctionTemplateDefinition<br>
+                                   : TPC_FriendFunctionTemplate)<br>
+                              : (D.getCXXScopeSpec().isSet() &&<br>
+                                 DC && DC->isRecord())<br>
+                                  ? TPC_ClassTemplateMember<br>
+                                  : TPC_FunctionTemplate);<br>
     }<br>
<br>
     if (NewFD->isInvalidDecl()) {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=124856&r1=124855&r2=124856&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=124856&r1=124855&r2=124856&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Feb  3 22:20:44 2011<br>
@@ -946,7 +946,10 @@<br>
   // template declaration.<br>
   if (CheckTemplateParameterList(TemplateParams,<br>
             PrevClassTemplate? PrevClassTemplate->getTemplateParameters() : 0,<br>
-                                 TPC_ClassTemplate))<br>
+                                 (SS.isSet() && SemanticContext &&<br>
+                                  SemanticContext->isRecord())<br>
+                                   ? TPC_ClassTemplateMember<br>
+                                   : TPC_ClassTemplate))<br>
     Invalid = true;<br>
<br>
   if (SS.isSet()) {<br>
@@ -1045,11 +1048,15 @@<br>
     return false;<br>
<br>
   case Sema::TPC_FunctionTemplate:<br>
+  case Sema::TPC_FriendFunctionTemplateDefinition:<br>
     // C++ [temp.param]p9:<br>
     //   A default template-argument shall not be specified in a<br>
     //   function template declaration or a function template<br>
     //   definition [...]<br>
-    // (This sentence is not in C++0x, per DR226).<br>
+    //   If a friend function template declaration specifies a default<br>
+    //   template-argument, that declaration shall be a definition and shall be<br>
+    //   the only declaration of the function template in the translation unit.<br>
+    // (C++98/03 doesn't have this wording; see DR226).<br>
     if (!S.getLangOptions().CPlusPlus0x)<br>
       S.Diag(ParamLoc,<br>
              diag::ext_template_parameter_default_in_function_template)<br>
<br>
Modified: cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp?rev=124856&r1=124855&r2=124856&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp?rev=124856&r1=124855&r2=124856&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp (original)<br>
+++ cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp Thu Feb  3 22:20:44 2011<br>
@@ -12,3 +12,41 @@<br>
<br>
 template<template<class> class ...Templates = vector> // expected-error{{template parameter pack cannot have a default argument}}<br>
 struct X2;<br>
+<br>
+struct X3 {<br>
+  template<typename T = int> // expected-error{{default template argument not permitted on a friend template}}<br>
+  friend void f0(X3);<br>
+<br>
+  template<typename T = int><br>
+  friend void f1(X3) {<br>
+  }<br>
+};<br>
+<br>
+namespace PR8747 {<br>
+  // Testcase 1<br>
+  struct A0 { template<typename U> struct B; };<br>
+  template<typename U = int> struct A0::B { }; // expected-error{{cannot add a default template argument to the definition of a member of a class template}}<br>
+<br>
+  // Testcase 2<br>
+  template<typename T> struct A1 { template<typename U> struct B; };<br>
+  template<typename T> template<typename U = int> struct A1<T>::B { }; // expected-error{{cannot add a default template argument to the definition of a member of a class template}}<br>
+<br>
+  // Testcase 3<br>
+  template<typename T><br>
+  struct X2 {<br>
+    void f0();<br>
+    template<typename U> void f1();<br>
+  };<br>
+<br>
+  template<typename T = int> void X2<T>::f0() { } // expected-error{{cannot add a default template argument to the definition of a member of a class template}}<br>
+  template<typename T> template<typename U = int> void X2<T>::f1() { } // expected-error{{cannot add a default template argument to the definition of a member of a class template}}<br>
+<br>
+  namespace Inner {<br>
+    template<typename T> struct X3;<br>
+    template<typename T> void f2();<br>
+  }<br>
+<br>
+  // Okay; not class members.<br>
+  template<typename T = int> struct Inner::X3 { };<br>
+  template<typename T = int> void Inner::f2() {}<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br>
</blockquote></div><br></div></body></html>