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
This commit is contained in:
Marek Polacek 2019-01-28 22:14:27 +00:00 committed by Marek Polacek
parent 2c5b392032
commit b6d0f41ac5
6 changed files with 54 additions and 18 deletions

View File

@ -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.

View File

@ -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;
}
}
}

View File

@ -1,3 +1,11 @@
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.

View File

@ -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;

View File

@ -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>;
}

View File

@ -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);