diff options
author | Marek Polacek <polacek@redhat.com> | 2019-01-28 22:14:27 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2019-01-28 22:14:27 +0000 |
commit | b6d0f41ac5c1786911858b4763bb6f92519166f4 (patch) | |
tree | ca1b40716b10b941b960f762ca38414b38cab433 /gcc | |
parent | 2c5b39203276b00496ef32468ccb61d445aef97b (diff) | |
download | gcc-b6d0f41ac5c1786911858b4763bb6f92519166f4.zip gcc-b6d0f41ac5c1786911858b4763bb6f92519166f4.tar.gz gcc-b6d0f41ac5c1786911858b4763bb6f92519166f4.tar.bz2 |
PR c++/88358 - name wrongly treated as type.
* parser.c (cp_parser_direct_declarator): Don't assume a qualified-id
in parameter-list is a type if the function's declarator-id is not
qualified.
* g++.dg/cpp2a/typename1.C: Add dg-error.
* g++.dg/cpp2a/typename13.C: New test.
* g++.dg/cpp2a/typename6.C: Make a function name qualified.
Add typename.
From-SVN: r268343
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/parser.c | 31 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/typename1.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/typename13.C | 13 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp2a/typename6.C | 11 |
6 files changed, 54 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dcac8e7..5e2f69d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-01-28 Marek Polacek <polacek@redhat.com> + + PR c++/88358 - name wrongly treated as type. + * parser.c (cp_parser_direct_declarator): Don't assume a qualified-id + in parameter-list is a type if the function's declarator-id is not + qualified. + 2019-01-27 Marek Polacek <polacek@redhat.com> PR c++/88815 - narrowing conversion lost in decltype. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index dc9d651..16f2a32 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -21107,23 +21107,28 @@ cp_parser_direct_declarator (cp_parser* parser, 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)) + /* ...whose declarator-id is qualified. If it isn't, never + assume the parameters to refer to types. */ + if (qualifying_scope == NULL_TREE) flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL; + else + { + /* 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; + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a36e19c..7af76a1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,13 @@ 2019-01-28 Marek Polacek <polacek@redhat.com> + PR c++/88358 - name wrongly treated as type. + * g++.dg/cpp2a/typename1.C: Add dg-error. + * g++.dg/cpp2a/typename13.C: New test. + * g++.dg/cpp2a/typename6.C: Make a function name qualified. + Add typename. + +2019-01-28 Marek Polacek <polacek@redhat.com> + * g++.dg/cpp0x/enum37.C: Add dg-error. 2019-01-28 Bernd Edlinger <bernd.edlinger@hotmail.de> diff --git a/gcc/testsuite/g++.dg/cpp2a/typename1.C b/gcc/testsuite/g++.dg/cpp2a/typename1.C index 833d3b8..0c1f630 100644 --- a/gcc/testsuite/g++.dg/cpp2a/typename1.C +++ b/gcc/testsuite/g++.dg/cpp2a/typename1.C @@ -6,7 +6,7 @@ template<class T> T::R f(); // Ill-formed (no diagnostic required), attempt to declare // a void variable template -template<class T> void f(T::R); +template<class T> void f(T::R); // { dg-error "declared void" } template <class T> struct A; template <class T> using B = A<T>::U; diff --git a/gcc/testsuite/g++.dg/cpp2a/typename13.C b/gcc/testsuite/g++.dg/cpp2a/typename13.C new file mode 100644 index 0000000..c439f72 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/typename13.C @@ -0,0 +1,13 @@ +// P0634R3, PR c++/88358 +// { dg-do compile { target c++2a } } + +template <typename T> +int pi(T::your_pi); + +struct Foo { static constexpr int your_pi = 10; }; + +int +main () +{ + return pi<Foo>; +} diff --git a/gcc/testsuite/g++.dg/cpp2a/typename6.C b/gcc/testsuite/g++.dg/cpp2a/typename6.C index 49e2235..e96e2ab 100644 --- a/gcc/testsuite/g++.dg/cpp2a/typename6.C +++ b/gcc/testsuite/g++.dg/cpp2a/typename6.C @@ -55,11 +55,14 @@ struct S2 { // (5.2.4) parameter-declaration in a declarator of a function or function // template declaration whose declarator-id is qualified, // unless that parameter-declaration appears in a default argument -template<typename T> -int fn3 (T::X); + +struct M { + template<typename T> + int fn (T::X); +}; template<typename T> -int fn4 (T::X p) { return p; } +int M::fn (T::X p) { return p; } // (5.2.5) parameter-declaration in a lambda-declarator, // unless that parameter-declaration appears in a default argument @@ -92,7 +95,7 @@ struct S5 { }; template<typename T> -void fn7 (T::X p) +void fn7 (typename T::X p) { int i = static_cast<T::Y>(p); i = dynamic_cast<T::Y>(p); |