diff options
author | Marek Polacek <polacek@redhat.com> | 2019-01-23 17:25:42 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2019-01-23 17:25:42 +0000 |
commit | 4aab08286ae06a5567b75c85ab784cfe44355079 (patch) | |
tree | def2b98b57824fb355185520514370b3485c6791 /gcc | |
parent | 6770fa53f9debd0cced4b1016c8e388512859ee3 (diff) | |
download | gcc-4aab08286ae06a5567b75c85ab784cfe44355079.zip gcc-4aab08286ae06a5567b75c85ab784cfe44355079.tar.gz gcc-4aab08286ae06a5567b75c85ab784cfe44355079.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/parser.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/dependent2.C | 10 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/typename10.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/typename12.C | 20 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/static30.C | 2 |
7 files changed, 74 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a36fe31..58acbf0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-01-23 Marek Polacek <polacek@redhat.com> + + 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 <jakub@redhat.com> PR c/44715 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 7d7b029..dc9d651 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 <typename T> 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 38fec83..b0b1afa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-01-23 Marek Polacek <polacek@redhat.com> + + 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 <jakub@redhat.com> 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 0000000..a0740d4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/dependent2.C @@ -0,0 +1,10 @@ +// PR c++/88757 +// { dg-do compile { target c++11 } } + +template <class T> struct C { + static int x; +}; +template <class U> struct S { + static const int size = 1; +}; +template <class T> int C<T>::x(S<T>::size); diff --git a/gcc/testsuite/g++.dg/cpp2a/typename10.C b/gcc/testsuite/g++.dg/cpp2a/typename10.C index fa2cd00..1413268 100644 --- a/gcc/testsuite/g++.dg/cpp2a/typename10.C +++ b/gcc/testsuite/g++.dg/cpp2a/typename10.C @@ -11,7 +11,7 @@ namespace N2 { template<typename T> extern T::type v; // #1a //template<typename T> T::type v(typename T::value); // #1b } -template<typename T> T::type N2::v(T::value); // { dg-error "" } +template<typename T> T::type N2::v(T::value); namespace A { inline namespace B { template<typename T> 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 0000000..97962e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/typename12.C @@ -0,0 +1,20 @@ +// P0634R3 +// { dg-do compile { target c++2a } } + +struct W { + template<typename T> + static int fn1 (T::X); + template<typename T> + static int fn2 (T::X); + template<typename T> + static int fn2 (T::X, int); +}; + +template<typename T> +int W::fn1 (T::X p) { return p; } + +template<typename T> +int W::fn2 (T::X p) { return p; } + +template<typename T> +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 8b8637a..07dafe2 100644 --- a/gcc/testsuite/g++.dg/template/static30.C +++ b/gcc/testsuite/g++.dg/template/static30.C @@ -6,5 +6,5 @@ template <int> struct A static const int i2; }; -template <int N> const int A<N>::i1(A<N>::i); // { dg-error "no declaration matches" "" { target c++2a } } +template <int N> const int A<N>::i1(A<N>::i); template <int N> const int A<N>::i2(3, A<N>::i); // { dg-error "expression list" } |