From: Marek Polacek Date: Wed, 23 Jan 2019 17:25:42 +0000 (+0000) Subject: PR c++/88757 - qualified name treated wrongly as type. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4aab08286ae06a5567b75c85ab784cfe44355079;p=gcc.git PR c++/88757 - qualified name treated wrongly as type. * parser.c (cp_parser_direct_declarator): don't treat qualified-ids in parameter-list as types if name lookup for declarator-id didn't find one or more function templates. * g++.dg/cpp0x/dependent2.c: new test. * g++.dg/cpp2a/typename10.c: remove dg-error. * g++.dg/cpp2a/typename12.c: new test. * g++.dg/template/static30.c: remove dg-error. From-SVN: r268192 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a36fe31ca23..58acbf0a241 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-01-23 Marek Polacek + + PR c++/88757 - qualified name treated wrongly as type. + * parser.c (cp_parser_direct_declarator): Don't treat qualified-ids + in parameter-list as types if name lookup for declarator-id didn't + find one or more function templates. + 2019-01-23 Jakub Jelinek PR c/44715 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7d7b0292650..dc9d651308a 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -21098,6 +21098,33 @@ cp_parser_direct_declarator (cp_parser* parser, if (pack_expansion_p) maybe_warn_variadic_templates (); + + /* We're looking for this case in [temp.res]: + A qualified-id is assumed to name a type if [...] + - it is a decl-specifier of the decl-specifier-seq of a + parameter-declaration in a declarator of a function or + function template declaration, ... */ + if (cxx_dialect >= cxx2a + && (flags & CP_PARSER_FLAGS_TYPENAME_OPTIONAL) + && declarator->kind == cdk_id + /* ...whose declarator-id is qualified. */ + && qualifying_scope != NULL_TREE + && !at_class_scope_p () + && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)) + { + /* Now we have something like + template int C::x(S::p); + which can be a function template declaration or a + variable template definition. If name lookup for + the declarator-id C::x finds one or more function + templates, assume S::p to name a type. Otherwise, + don't. */ + tree decl + = cp_parser_lookup_name_simple (parser, unqualified_name, + token->location); + if (!is_overloaded_fn (decl)) + flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL; + } } handle_declarator:; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 38fec831cb8..b0b1afa9cf0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-01-23 Marek Polacek + + PR c++/88757 - qualified name treated wrongly as type. + * g++.dg/cpp0x/dependent2.C: New test. + * g++.dg/cpp2a/typename10.C: Remove dg-error. + * g++.dg/cpp2a/typename12.C: New test. + * g++.dg/template/static30.C: Remove dg-error. + 2019-01-23 Jakub Jelinek PR c/44715 diff --git a/gcc/testsuite/g++.dg/cpp0x/dependent2.C b/gcc/testsuite/g++.dg/cpp0x/dependent2.C new file mode 100644 index 00000000000..a0740d404a3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/dependent2.C @@ -0,0 +1,10 @@ +// PR c++/88757 +// { dg-do compile { target c++11 } } + +template struct C { + static int x; +}; +template struct S { + static const int size = 1; +}; +template int C::x(S::size); diff --git a/gcc/testsuite/g++.dg/cpp2a/typename10.C b/gcc/testsuite/g++.dg/cpp2a/typename10.C index fa2cd000b5d..1413268ba16 100644 --- a/gcc/testsuite/g++.dg/cpp2a/typename10.C +++ b/gcc/testsuite/g++.dg/cpp2a/typename10.C @@ -11,7 +11,7 @@ namespace N2 { template extern T::type v; // #1a //template T::type v(typename T::value); // #1b } -template T::type N2::v(T::value); // { dg-error "" } +template T::type N2::v(T::value); namespace A { inline namespace B { template int f(typename T::foo); } diff --git a/gcc/testsuite/g++.dg/cpp2a/typename12.C b/gcc/testsuite/g++.dg/cpp2a/typename12.C new file mode 100644 index 00000000000..97962e53d65 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/typename12.C @@ -0,0 +1,20 @@ +// P0634R3 +// { dg-do compile { target c++2a } } + +struct W { + template + static int fn1 (T::X); + template + static int fn2 (T::X); + template + static int fn2 (T::X, int); +}; + +template +int W::fn1 (T::X p) { return p; } + +template +int W::fn2 (T::X p) { return p; } + +template +int fn2 (typename T::X p) { return p; } diff --git a/gcc/testsuite/g++.dg/template/static30.C b/gcc/testsuite/g++.dg/template/static30.C index 8b8637a1abe..07dafe23ffa 100644 --- a/gcc/testsuite/g++.dg/template/static30.C +++ b/gcc/testsuite/g++.dg/template/static30.C @@ -6,5 +6,5 @@ template struct A static const int i2; }; -template const int A::i1(A::i); // { dg-error "no declaration matches" "" { target c++2a } } +template const int A::i1(A::i); template const int A::i2(3, A::i); // { dg-error "expression list" }