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:
parent
2c5b392032
commit
b6d0f41ac5
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>;
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue