<div dir="ltr">Bill, r196333, r196335, r196337 are all OK for the branch if you want to take them.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Dec 3, 2013 at 6:20 PM, Chandler Carruth <span dir="ltr"><<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Richard, Bill, would this OK for 3.4 still? It just seems like something folks could hit quite often playing with new C++14 features.</div>
<div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Dec 3, 2013 at 4:28 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard-llvm@metafoo.co.uk" target="_blank">richard-llvm@metafoo.co.uk</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rsmith<br>
Date: Tue Dec  3 18:28:23 2013<br>
New Revision: 196333<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=196333&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=196333&view=rev</a><br>
Log:<br>
Fix several crash-on-invalids when using template-ids that aren't<br>
simple-template-ids (eg, 'operator+<int>') in weird places.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br>
    cfe/trunk/include/clang/Basic/TemplateKinds.h<br>
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
    cfe/trunk/lib/Parse/ParseExprCXX.cpp<br>
    cfe/trunk/lib/Parse/Parser.cpp<br>
    cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
    cfe/trunk/test/CXX/drs/dr3xx.cpp<br>
    cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=196333&r1=196332&r2=196333&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=196333&r1=196332&r2=196333&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Dec  3 18:28:23 2013<br>
@@ -578,8 +578,8 @@ def err_class_on_template_template_param<br>
   "template template parameter requires 'class' after the parameter list">;<br>
 def err_template_spec_syntax_non_template : Error<<br>
   "identifier followed by '<' indicates a class template specialization but "<br>
-  "%0 %select{does not refer to a template|refers to a function "<br>
-  "template|<unused>|refers to a template template parameter}1">;<br>
+  "%0 %select{does not refer to a template|refers to a function template|"<br>
+  "<unused>|refers to a variable template|<unused>}1">;<br>
 def err_id_after_template_in_nested_name_spec : Error<<br>
   "expected template name after 'template' keyword in nested name specifier">;<br>
 def err_two_right_angle_brackets_need_space : Error<<br>
@@ -643,7 +643,7 @@ def err_expected_semi_after_tagdecl : Er<br>
   "expected ';' after %0">;<br>
<br>
 def err_typename_refers_to_non_type_template : Error<<br>
-  "typename specifier refers to a non-template">;<br>
+  "typename specifier refers to a non-type template">;<br>
 def err_expected_type_name_after_typename : Error<<br>
   "expected an identifier or template-id after '::'">;<br>
 def err_explicit_spec_non_template : Error<<br>
<br>
Modified: cfe/trunk/include/clang/Basic/TemplateKinds.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TemplateKinds.h?rev=196333&r1=196332&r2=196333&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TemplateKinds.h?rev=196333&r1=196332&r2=196333&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Basic/TemplateKinds.h (original)<br>
+++ cfe/trunk/include/clang/Basic/TemplateKinds.h Tue Dec  3 18:28:23 2013<br>
@@ -17,6 +17,7 @@<br>
 namespace clang {<br>
<br>
 /// \brief Specifies the kind of template name that an identifier refers to.<br>
+/// Be careful when changing this: this enumeration is used in diagnostics.<br>
 enum TemplateNameKind {<br>
   /// The name does not refer to a template.<br>
   TNK_Non_template = 0,<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=196333&r1=196332&r2=196333&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=196333&r1=196332&r2=196333&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Dec  3 18:28:23 2013<br>
@@ -1287,6 +1287,7 @@ void Parser::ParseClassSpecifier(tok::To<br>
       if (SS.isNotEmpty())<br>
         Range.setBegin(SS.getBeginLoc());<br>
<br>
+      // FIXME: Name may be null here.<br>
       Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)<br>
         << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range;<br>
<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=196333&r1=196332&r2=196333&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=196333&r1=196332&r2=196333&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Dec  3 18:28:23 2013<br>
@@ -341,10 +341,10 @@ bool Parser::ParseOptionalCXXScopeSpecif<br>
     if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {<br>
       // We have<br>
       //<br>
-      //   simple-template-id '::'<br>
+      //   template-id '::'<br>
       //<br>
-      // So we need to check whether the simple-template-id is of the<br>
-      // right kind (it should name a type or be dependent), and then<br>
+      // So we need to check whether the template-id is a simple-template-id of<br>
+      // the right kind (it should name a type or be dependent), and then<br>
       // convert it into a type within the nested-name-specifier.<br>
       TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);<br>
       if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {<br>
@@ -1882,6 +1882,7 @@ bool Parser::ParseUnqualifiedIdTemplateI<br>
     TemplateIdAnnotation *TemplateId<br>
       = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);<br>
<br>
+    // FIXME: Store name for literal operator too.<br>
     if (Id.getKind() == UnqualifiedId::IK_Identifier) {<br>
       TemplateId->Name = Id.Identifier;<br>
       TemplateId->Operator = OO_None;<br>
<br>
Modified: cfe/trunk/lib/Parse/Parser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=196333&r1=196332&r2=196333&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=196333&r1=196332&r2=196333&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Parse/Parser.cpp (original)<br>
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Dec  3 18:28:23 2013<br>
@@ -1615,7 +1615,8 @@ bool Parser::TryAnnotateTypeOrScopeToken<br>
                                      Tok.getLocation());<br>
     } else if (Tok.is(tok::annot_template_id)) {<br>
       TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);<br>
-      if (TemplateId->Kind == TNK_Function_template) {<br>
+      if (TemplateId->Kind != TNK_Type_template &&<br>
+          TemplateId->Kind != TNK_Dependent_template_name) {<br>
         Diag(Tok, diag::err_typename_refers_to_non_type_template)<br>
           << Tok.getAnnotationRange();<br>
         return true;<br>
@@ -1740,6 +1741,8 @@ bool Parser::TryAnnotateTypeOrScopeToken<br>
       AnnotateTemplateIdTokenAsType();<br>
       return false;<br>
     } else if (TemplateId->Kind == TNK_Var_template)<br>
+      // FIXME: This looks suspicious. Why are we not annotating the scope token<br>
+      // in this case?<br>
       return false;<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=196333&r1=196332&r2=196333&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=196333&r1=196332&r2=196333&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Tue Dec  3 18:28:23 2013<br>
@@ -747,7 +747,8 @@ bool Sema::ActOnCXXNestedNameSpecifier(S<br>
   TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);<br>
   translateTemplateArguments(TemplateArgsIn, TemplateArgs);<br>
<br>
-  if (DependentTemplateName *DTN = Template.get().getAsDependentTemplateName()){<br>
+  DependentTemplateName *DTN = Template.get().getAsDependentTemplateName();<br>
+  if (DTN && DTN->isIdentifier()) {<br>
     // Handle a dependent template specialization for which we cannot resolve<br>
     // the template name.<br>
     assert(DTN->getQualifier() == SS.getScopeRep());<br>
@@ -773,20 +774,20 @@ bool Sema::ActOnCXXNestedNameSpecifier(S<br>
               CCLoc);<br>
     return false;<br>
   }<br>
-<br>
-<br>
-  if (Template.get().getAsOverloadedTemplate() ||<br>
+<br>
+  // FIXME: Variable templates<br>
+  if (Template.get().getAsOverloadedTemplate() || DTN ||<br>
       isa<FunctionTemplateDecl>(Template.get().getAsTemplateDecl())) {<br>
     SourceRange R(TemplateNameLoc, RAngleLoc);<br>
     if (SS.getRange().isValid())<br>
       R.setBegin(SS.getRange().getBegin());<br>
-<br>
+<br>
     Diag(CCLoc, diag::err_non_type_template_in_nested_name_specifier)<br>
       << Template.get() << R;<br>
     NoteAllFoundTemplates(Template.get());<br>
     return true;<br>
   }<br>
-<br>
+<br>
   // We were able to resolve the template name to an actual template.<br>
   // Build an appropriate nested-name-specifier.<br>
   QualType T = CheckTemplateIdType(Template.get(), TemplateNameLoc,<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=196333&r1=196332&r2=196333&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=196333&r1=196332&r2=196333&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Dec  3 18:28:23 2013<br>
@@ -2910,7 +2910,7 @@ TemplateNameKind Sema::ActOnDependentTem<br>
   case UnqualifiedId::IK_OperatorFunctionId:<br>
     Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,<br>
                                              Name.OperatorFunctionId.Operator));<br>
-    return TNK_Dependent_template_name;<br>
+    return TNK_Function_template;<br>
<br>
   case UnqualifiedId::IK_LiteralOperatorId:<br>
     llvm_unreachable(<br>
<br>
Modified: cfe/trunk/test/CXX/drs/dr3xx.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr3xx.cpp?rev=196333&r1=196332&r2=196333&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr3xx.cpp?rev=196333&r1=196332&r2=196333&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/CXX/drs/dr3xx.cpp (original)<br>
+++ cfe/trunk/test/CXX/drs/dr3xx.cpp Tue Dec  3 18:28:23 2013<br>
@@ -8,4 +8,29 @@ namespace dr300 { // dr300: yes<br>
   void h() { f(g); }<br>
 }<br>
<br>
-// expected-no-diagnostics<br>
+namespace dr301 { // dr301 WIP<br>
+  // see also dr38<br>
+  struct S;<br>
+  template<typename T> void operator+(T, T);<br>
+  void operator-(S, S);<br>
+<br>
+  void f() {<br>
+    bool a = (void(*)(S, S))operator+<S> <<br>
+             (void(*)(S, S))operator+<S>;<br>
+    bool b = (void(*)(S, S))operator- <<br>
+             (void(*)(S, S))operator-;<br>
+    bool c = (void(*)(S, S))operator+ <<br>
+             (void(*)(S, S))operator-; // expected-error {{expected '>'}}<br>
+  }<br>
+<br>
+  template<typename T> void f() {<br>
+    typename T::template operator+<int> a; // expected-error {{typename specifier refers to a non-type template}} expected-error +{{}}<br>
+    // FIXME: This shouldn't say (null).<br>
+    class T::template operator+<int> b; // expected-error {{identifier followed by '<' indicates a class template specialization but (null) refers to a function template}}<br>
+    enum T::template operator+<int> c; // expected-error {{expected identifier}} expected-error {{does not declare anything}}<br>
+    enum T::template operator+<int>::E d; // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}} expected-error {{forward reference}}<br>
+    enum T::template X<int>::E e;<br>
+    T::template operator+<int>::foobar(); // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}}<br>
+    T::template operator+<int>(0); // ok<br>
+  }<br>
+}<br>
<br>
Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp?rev=196333&r1=196332&r2=196333&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp?rev=196333&r1=196332&r2=196333&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp Tue Dec  3 18:28:23 2013<br>
@@ -432,3 +432,11 @@ namespace nested {<br>
   }<br>
 }<br>
<br>
+namespace nested_name {<br>
+  template<typename T> int a;<br>
+  // FIXME: This triggers a crash.<br>
+  //a<int>::b c;<br>
+<br>
+  class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}<br>
+  enum a<int> {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}}<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">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></div>
</div></div></blockquote></div><br></div>