+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.
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;
+ }
}
}
+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.
// 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;
// (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
};
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);