r196333 - Fix several crash-on-invalids when using template-ids that aren't

Bill Wendling isanbard at gmail.com
Sat Dec 7 15:48:00 PST 2013


r196333 doesn’t apply cleanly. The ‘test/CXX/drs/dr3xx.cpp’ file doesn’t exist in the branch. Are we missing some patches? :)

-bw

On Dec 3, 2013, at 6:25 PM, Richard Smith <richard at metafoo.co.uk> wrote:

> Bill, r196333, r196335, r196337 are all OK for the branch if you want to take them.
> 
> 
> On Tue, Dec 3, 2013 at 6:20 PM, Chandler Carruth <chandlerc at google.com> wrote:
> 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.
> 
> 
> On Tue, Dec 3, 2013 at 4:28 PM, Richard Smith <richard-llvm at metafoo.co.uk> wrote:
> Author: rsmith
> Date: Tue Dec  3 18:28:23 2013
> New Revision: 196333
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=196333&view=rev
> Log:
> Fix several crash-on-invalids when using template-ids that aren't
> simple-template-ids (eg, 'operator+<int>') in weird places.
> 
> Modified:
>     cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
>     cfe/trunk/include/clang/Basic/TemplateKinds.h
>     cfe/trunk/lib/Parse/ParseDeclCXX.cpp
>     cfe/trunk/lib/Parse/ParseExprCXX.cpp
>     cfe/trunk/lib/Parse/Parser.cpp
>     cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
>     cfe/trunk/lib/Sema/SemaTemplate.cpp
>     cfe/trunk/test/CXX/drs/dr3xx.cpp
>     cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
> 
> Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=196333&r1=196332&r2=196333&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Dec  3 18:28:23 2013
> @@ -578,8 +578,8 @@ def err_class_on_template_template_param
>    "template template parameter requires 'class' after the parameter list">;
>  def err_template_spec_syntax_non_template : Error<
>    "identifier followed by '<' indicates a class template specialization but "
> -  "%0 %select{does not refer to a template|refers to a function "
> -  "template|<unused>|refers to a template template parameter}1">;
> +  "%0 %select{does not refer to a template|refers to a function template|"
> +  "<unused>|refers to a variable template|<unused>}1">;
>  def err_id_after_template_in_nested_name_spec : Error<
>    "expected template name after 'template' keyword in nested name specifier">;
>  def err_two_right_angle_brackets_need_space : Error<
> @@ -643,7 +643,7 @@ def err_expected_semi_after_tagdecl : Er
>    "expected ';' after %0">;
> 
>  def err_typename_refers_to_non_type_template : Error<
> -  "typename specifier refers to a non-template">;
> +  "typename specifier refers to a non-type template">;
>  def err_expected_type_name_after_typename : Error<
>    "expected an identifier or template-id after '::'">;
>  def err_explicit_spec_non_template : Error<
> 
> Modified: cfe/trunk/include/clang/Basic/TemplateKinds.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TemplateKinds.h?rev=196333&r1=196332&r2=196333&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/TemplateKinds.h (original)
> +++ cfe/trunk/include/clang/Basic/TemplateKinds.h Tue Dec  3 18:28:23 2013
> @@ -17,6 +17,7 @@
>  namespace clang {
> 
>  /// \brief Specifies the kind of template name that an identifier refers to.
> +/// Be careful when changing this: this enumeration is used in diagnostics.
>  enum TemplateNameKind {
>    /// The name does not refer to a template.
>    TNK_Non_template = 0,
> 
> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=196333&r1=196332&r2=196333&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Dec  3 18:28:23 2013
> @@ -1287,6 +1287,7 @@ void Parser::ParseClassSpecifier(tok::To
>        if (SS.isNotEmpty())
>          Range.setBegin(SS.getBeginLoc());
> 
> +      // FIXME: Name may be null here.
>        Diag(TemplateId->LAngleLoc, diag::err_template_spec_syntax_non_template)
>          << TemplateId->Name << static_cast<int>(TemplateId->Kind) << Range;
> 
> 
> Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=196333&r1=196332&r2=196333&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Dec  3 18:28:23 2013
> @@ -341,10 +341,10 @@ bool Parser::ParseOptionalCXXScopeSpecif
>      if (Tok.is(tok::annot_template_id) && NextToken().is(tok::coloncolon)) {
>        // We have
>        //
> -      //   simple-template-id '::'
> +      //   template-id '::'
>        //
> -      // So we need to check whether the simple-template-id is of the
> -      // right kind (it should name a type or be dependent), and then
> +      // So we need to check whether the template-id is a simple-template-id of
> +      // the right kind (it should name a type or be dependent), and then
>        // convert it into a type within the nested-name-specifier.
>        TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
>        if (CheckForDestructor && GetLookAheadToken(2).is(tok::tilde)) {
> @@ -1882,6 +1882,7 @@ bool Parser::ParseUnqualifiedIdTemplateI
>      TemplateIdAnnotation *TemplateId
>        = TemplateIdAnnotation::Allocate(TemplateArgs.size(), TemplateIds);
> 
> +    // FIXME: Store name for literal operator too.
>      if (Id.getKind() == UnqualifiedId::IK_Identifier) {
>        TemplateId->Name = Id.Identifier;
>        TemplateId->Operator = OO_None;
> 
> Modified: cfe/trunk/lib/Parse/Parser.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=196333&r1=196332&r2=196333&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/Parser.cpp (original)
> +++ cfe/trunk/lib/Parse/Parser.cpp Tue Dec  3 18:28:23 2013
> @@ -1615,7 +1615,8 @@ bool Parser::TryAnnotateTypeOrScopeToken
>                                       Tok.getLocation());
>      } else if (Tok.is(tok::annot_template_id)) {
>        TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
> -      if (TemplateId->Kind == TNK_Function_template) {
> +      if (TemplateId->Kind != TNK_Type_template &&
> +          TemplateId->Kind != TNK_Dependent_template_name) {
>          Diag(Tok, diag::err_typename_refers_to_non_type_template)
>            << Tok.getAnnotationRange();
>          return true;
> @@ -1740,6 +1741,8 @@ bool Parser::TryAnnotateTypeOrScopeToken
>        AnnotateTemplateIdTokenAsType();
>        return false;
>      } else if (TemplateId->Kind == TNK_Var_template)
> +      // FIXME: This looks suspicious. Why are we not annotating the scope token
> +      // in this case?
>        return false;
>    }
> 
> 
> Modified: cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp?rev=196333&r1=196332&r2=196333&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp Tue Dec  3 18:28:23 2013
> @@ -747,7 +747,8 @@ bool Sema::ActOnCXXNestedNameSpecifier(S
>    TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
>    translateTemplateArguments(TemplateArgsIn, TemplateArgs);
> 
> -  if (DependentTemplateName *DTN = Template.get().getAsDependentTemplateName()){
> +  DependentTemplateName *DTN = Template.get().getAsDependentTemplateName();
> +  if (DTN && DTN->isIdentifier()) {
>      // Handle a dependent template specialization for which we cannot resolve
>      // the template name.
>      assert(DTN->getQualifier() == SS.getScopeRep());
> @@ -773,20 +774,20 @@ bool Sema::ActOnCXXNestedNameSpecifier(S
>                CCLoc);
>      return false;
>    }
> -
> -
> -  if (Template.get().getAsOverloadedTemplate() ||
> +
> +  // FIXME: Variable templates
> +  if (Template.get().getAsOverloadedTemplate() || DTN ||
>        isa<FunctionTemplateDecl>(Template.get().getAsTemplateDecl())) {
>      SourceRange R(TemplateNameLoc, RAngleLoc);
>      if (SS.getRange().isValid())
>        R.setBegin(SS.getRange().getBegin());
> -
> +
>      Diag(CCLoc, diag::err_non_type_template_in_nested_name_specifier)
>        << Template.get() << R;
>      NoteAllFoundTemplates(Template.get());
>      return true;
>    }
> -
> +
>    // We were able to resolve the template name to an actual template.
>    // Build an appropriate nested-name-specifier.
>    QualType T = CheckTemplateIdType(Template.get(), TemplateNameLoc,
> 
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=196333&r1=196332&r2=196333&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Dec  3 18:28:23 2013
> @@ -2910,7 +2910,7 @@ TemplateNameKind Sema::ActOnDependentTem
>    case UnqualifiedId::IK_OperatorFunctionId:
>      Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
>                                               Name.OperatorFunctionId.Operator));
> -    return TNK_Dependent_template_name;
> +    return TNK_Function_template;
> 
>    case UnqualifiedId::IK_LiteralOperatorId:
>      llvm_unreachable(
> 
> Modified: cfe/trunk/test/CXX/drs/dr3xx.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr3xx.cpp?rev=196333&r1=196332&r2=196333&view=diff
> ==============================================================================
> --- cfe/trunk/test/CXX/drs/dr3xx.cpp (original)
> +++ cfe/trunk/test/CXX/drs/dr3xx.cpp Tue Dec  3 18:28:23 2013
> @@ -8,4 +8,29 @@ namespace dr300 { // dr300: yes
>    void h() { f(g); }
>  }
> 
> -// expected-no-diagnostics
> +namespace dr301 { // dr301 WIP
> +  // see also dr38
> +  struct S;
> +  template<typename T> void operator+(T, T);
> +  void operator-(S, S);
> +
> +  void f() {
> +    bool a = (void(*)(S, S))operator+<S> <
> +             (void(*)(S, S))operator+<S>;
> +    bool b = (void(*)(S, S))operator- <
> +             (void(*)(S, S))operator-;
> +    bool c = (void(*)(S, S))operator+ <
> +             (void(*)(S, S))operator-; // expected-error {{expected '>'}}
> +  }
> +
> +  template<typename T> void f() {
> +    typename T::template operator+<int> a; // expected-error {{typename specifier refers to a non-type template}} expected-error +{{}}
> +    // FIXME: This shouldn't say (null).
> +    class T::template operator+<int> b; // expected-error {{identifier followed by '<' indicates a class template specialization but (null) refers to a function template}}
> +    enum T::template operator+<int> c; // expected-error {{expected identifier}} expected-error {{does not declare anything}}
> +    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}}
> +    enum T::template X<int>::E e;
> +    T::template operator+<int>::foobar(); // expected-error {{qualified name refers into a specialization of function template 'T::template operator +'}}
> +    T::template operator+<int>(0); // ok
> +  }
> +}
> 
> Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp?rev=196333&r1=196332&r2=196333&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp (original)
> +++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_top_level.cpp Tue Dec  3 18:28:23 2013
> @@ -432,3 +432,11 @@ namespace nested {
>    }
>  }
> 
> +namespace nested_name {
> +  template<typename T> int a;
> +  // FIXME: This triggers a crash.
> +  //a<int>::b c;
> +
> +  class a<int> {}; // expected-error {{identifier followed by '<' indicates a class template specialization but 'a' refers to a variable template}}
> +  enum a<int> {}; // expected-error {{expected identifier or '{'}} expected-warning {{does not declare anything}}
> +}
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131207/ccea705f/attachment.html>


More information about the cfe-commits mailing list