r196333 - Fix several crash-on-invalids when using template-ids that aren't
Richard Smith
richard at metafoo.co.uk
Tue Dec 3 18:25:03 PST 2013
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/20131203/76b29598/attachment.html>
More information about the cfe-commits
mailing list