Commit 4aab0828 by Marek Polacek Committed by Marek Polacek

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
parent 6770fa53
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
......
......@@ -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:;
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
......
// 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);
......@@ -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); }
......
// 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; }
......@@ -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" }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment