re PR c++/14258 (typename in a using declaration not supported)
gcc/testsuite/ChangeLog 2011-12-11 Fabien Chene <fabien@gcc.gnu.org> PR c++/14258 * g++.dg/template/using16.C: New. * g++.dg/template/using17.C: New. gcc/cp/ChangeLog 2011-12-11 Fabien Chene <fabien@gcc.gnu.org> PR c++/14258 * cp-tree.h (USING_DECL_TYPENAME_P): New macro. * parser.c (cp_parser_nonclass_name): Handle using declarations that refer to a dependent type. (cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if the using declaration refers to a dependent type. From-SVN: r182292
This commit is contained in:
parent
863ea6cf55
commit
0f8fa9b678
|
@ -1,3 +1,12 @@
|
|||
2011-12-13 Fabien Chêne <fabien@gcc.gnu.org>
|
||||
|
||||
PR c++/14258
|
||||
* cp-tree.h (USING_DECL_TYPENAME_P): New macro.
|
||||
* parser.c (cp_parser_nonclass_name): Handle using declarations
|
||||
that refer to a dependent type.
|
||||
(cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if
|
||||
the using declaration refers to a dependent type.
|
||||
|
||||
2011-12-12 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/51496
|
||||
|
|
|
@ -130,6 +130,7 @@ c-common.h, not after.
|
|||
DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
|
||||
DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL)
|
||||
FUNCTION_PARAMETER_PACK_P (in PARM_DECL)
|
||||
USING_DECL_TYPENAME_P (in USING_DECL)
|
||||
2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
|
||||
DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
|
||||
3: DECL_IN_AGGR_P.
|
||||
|
@ -2521,6 +2522,9 @@ extern void decl_shadowed_for_var_insert (tree, tree);
|
|||
/* The decls named by a using decl. */
|
||||
#define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE))
|
||||
|
||||
/* Non zero if the using decl refers to a dependent type. */
|
||||
#define USING_DECL_TYPENAME_P(NODE) DECL_LANG_FLAG_1 (USING_DECL_CHECK (NODE))
|
||||
|
||||
/* In a VAR_DECL, true if we have a shadowed local variable
|
||||
in the shadowed var table for this VAR_DECL. */
|
||||
#define DECL_HAS_SHADOWED_FOR_VAR_P(NODE) \
|
||||
|
|
|
@ -13807,9 +13807,26 @@ cp_parser_nonclass_name (cp_parser* parser)
|
|||
/* Look up the type-name. */
|
||||
type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
|
||||
|
||||
/* If it is a using decl, use its underlying decl. */
|
||||
type_decl = strip_using_decl (type_decl);
|
||||
|
||||
if (TREE_CODE (type_decl) == USING_DECL)
|
||||
{
|
||||
if (!DECL_DEPENDENT_P (type_decl))
|
||||
type_decl = strip_using_decl (type_decl);
|
||||
else if (USING_DECL_TYPENAME_P (type_decl))
|
||||
{
|
||||
/* We have found a type introduced by a using
|
||||
declaration at class scope that refers to a dependent
|
||||
type.
|
||||
|
||||
using typename :: [opt] nested-name-specifier unqualified-id ;
|
||||
*/
|
||||
type_decl = make_typename_type (TREE_TYPE (type_decl),
|
||||
DECL_NAME (type_decl),
|
||||
typename_type, tf_error);
|
||||
if (type_decl != error_mark_node)
|
||||
type_decl = TYPE_NAME (type_decl);
|
||||
}
|
||||
}
|
||||
|
||||
if (TREE_CODE (type_decl) != TYPE_DECL
|
||||
&& (objc_is_id (identifier) || objc_is_class_name (identifier)))
|
||||
{
|
||||
|
@ -14947,6 +14964,9 @@ cp_parser_using_declaration (cp_parser* parser,
|
|||
/* Create the USING_DECL. */
|
||||
decl = do_class_using_decl (parser->scope, identifier);
|
||||
|
||||
if (typename_p)
|
||||
USING_DECL_TYPENAME_P (decl) = 1;
|
||||
|
||||
if (check_for_bare_parameter_packs (decl))
|
||||
return false;
|
||||
else
|
||||
|
@ -18900,7 +18920,11 @@ cp_parser_member_declaration (cp_parser* parser)
|
|||
parser->colon_corrects_to_scope_p = false;
|
||||
|
||||
if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
|
||||
goto out;
|
||||
{
|
||||
warning (OPT_Wdeprecated, "access declarations are deprecated; "
|
||||
"employ using declarations instead");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Parse the decl-specifier-seq. */
|
||||
decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2011-12-11 Fabien Chêne <fabien@gcc.gnu.org>
|
||||
|
||||
PR c++/14258
|
||||
* g++.dg/template/using16.C: New.
|
||||
* g++.dg/template/using17.C: New.
|
||||
|
||||
2011-12-13 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
PR tree-optimization/51362
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// { dg-do compile }
|
||||
|
||||
template <class T>
|
||||
struct A
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct B
|
||||
{
|
||||
class type
|
||||
{
|
||||
type(); // { dg-error "private" }
|
||||
};
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct C : A<T>, B<T>
|
||||
{
|
||||
using typename B<T>::type;
|
||||
|
||||
void f()
|
||||
{
|
||||
type j; // { dg-error "context" }
|
||||
}
|
||||
};
|
||||
|
||||
template class C<int>; // { dg-message "required" }
|
||||
|
||||
template <class T>
|
||||
struct D
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class E : D<T>
|
||||
{
|
||||
using typename D<T>::type; // { dg-message "previous" }
|
||||
using typename D<T>::type; // { dg-error "redeclaration" }
|
||||
};
|
|
@ -0,0 +1,44 @@
|
|||
// PR c++/14258
|
||||
// { dg-do run }
|
||||
|
||||
template<typename T>
|
||||
struct A
|
||||
{
|
||||
typedef T type;
|
||||
typedef A type2;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct B : A<T>
|
||||
{
|
||||
using typename A<T>::type;
|
||||
type t;
|
||||
|
||||
using typename A<T>::type2;
|
||||
|
||||
type f()
|
||||
{
|
||||
type i = 1;
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
B<int>::type t = 4;
|
||||
if (t != 4)
|
||||
__builtin_abort();
|
||||
|
||||
B<double> b;
|
||||
b.t = 3;
|
||||
if (b.t != 3)
|
||||
__builtin_abort();
|
||||
|
||||
B<long> b2;
|
||||
if (b2.f() != 1)
|
||||
__builtin_abort();
|
||||
|
||||
B<double>::type2::type tt = 12;
|
||||
if (tt != 12)
|
||||
__builtin_abort();
|
||||
}
|
Loading…
Reference in New Issue