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 <[email protected]>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 > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
