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
This commit is contained in:
parent
6770fa53f9
commit
4aab08286a
7 changed files with 74 additions and 2 deletions
|
@ -1,3 +1,10 @@
|
|||
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:;
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
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
|
||||
|
|
10
gcc/testsuite/g++.dg/cpp0x/dependent2.C
Normal file
10
gcc/testsuite/g++.dg/cpp0x/dependent2.C
Normal file
|
@ -0,0 +1,10 @@
|
|||
// 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); }
|
||||
|
|
20
gcc/testsuite/g++.dg/cpp2a/typename12.C
Normal file
20
gcc/testsuite/g++.dg/cpp2a/typename12.C
Normal file
|
@ -0,0 +1,20 @@
|
|||
// 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" }
|
||||
|
|
Loading…
Add table
Reference in a new issue