From: Fabien Chêne Date: Wed, 26 Feb 2014 21:16:15 +0000 (+0100) Subject: re PR c++/37140 (type inherited from base class not recognized) X-Git-Tag: releases/gcc-4.7.4~222 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a5953299b4f0336b1098765562dd65f5528893bd;p=thirdparty%2Fgcc.git re PR c++/37140 (type inherited from base class not recognized) 2014-02-26 Fabien Chene PR c++/37140 * parser.c (cp_parser_nonclass_name): Call strip_using_decl and move the code handling dependent USING_DECLs... * name-lookup.c (strip_using_decl): ...Here. 2014-02-26 Fabien Chene PR c++/37140 * g++.dg/template/using27.C: New. * g++.dg/template/using28.C: New. * g++.dg/template/using29.C: New. From-SVN: r208182 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index a27488a7936b..d22e15327d2d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2014-02-26 Fabien Chêne + PR c++/37140 + * parser.c (cp_parser_nonclass_name): Call strip_using_decl and + move the code handling dependent USING_DECLs... + * name-lookup.c (strip_using_decl): ...Here. + 2014-02-21 Jason Merrill PR c++/60248 diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 565d3966ca51..952903a7cd3b 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -399,7 +399,8 @@ pop_binding (tree id, tree decl) } } -/* Strip non dependent using declarations. */ +/* Strip non dependent using declarations. If DECL is dependent, + surreptitiously create a typename_type and return it. */ tree strip_using_decl (tree decl) @@ -409,6 +410,23 @@ strip_using_decl (tree decl) while (TREE_CODE (decl) == USING_DECL && !DECL_DEPENDENT_P (decl)) decl = USING_DECL_DECLS (decl); + + if (TREE_CODE (decl) == USING_DECL && DECL_DEPENDENT_P (decl) + && USING_DECL_TYPENAME_P (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 ; + */ + decl = make_typename_type (TREE_TYPE (decl), + DECL_NAME (decl), + typename_type, tf_error); + if (decl != error_mark_node) + decl = TYPE_NAME (decl); + } + return decl; } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index fe8c84df7955..120360a4d923 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13846,25 +13846,7 @@ cp_parser_nonclass_name (cp_parser* parser) /* Look up the type-name. */ type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location); - 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); - } - } + type_decl = strip_using_decl (type_decl); if (TREE_CODE (type_decl) != TYPE_DECL && (objc_is_id (identifier) || objc_is_class_name (identifier))) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fc5526c98119..4475c32a8ff0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-02-26 Fabien Chêne + + PR c++/37140 + * g++.dg/template/using27.C: New. + * g++.dg/template/using28.C: New. + * g++.dg/template/using29.C: New. + 2014-02-22 Mikael Morin PR fortran/59599 diff --git a/gcc/testsuite/g++.dg/template/using27.C b/gcc/testsuite/g++.dg/template/using27.C new file mode 100644 index 000000000000..f1835e17161c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using27.C @@ -0,0 +1,33 @@ +// PR c++/37140 + +struct X +{ + typedef int nested_type; +}; + +template +struct A +{ + typedef X type; +}; + +template +struct B : A +{ + using typename A::type; + typename type::nested_type x; +}; + +template +struct C : B +{ + using typename B::type; + typename type::nested_type y; +}; + +struct D : C +{ + using C::type; + type::nested_type z; +}; + diff --git a/gcc/testsuite/g++.dg/template/using28.C b/gcc/testsuite/g++.dg/template/using28.C new file mode 100644 index 000000000000..52f68cfe467b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using28.C @@ -0,0 +1,17 @@ +// PR c++/37140 + +struct C +{ + static const int block_size = 1; +}; + +template struct A { + typedef C type; +}; + +template struct B : public A { + using typename A::type; + static const int block_size = type::block_size; +}; + +template class B; diff --git a/gcc/testsuite/g++.dg/template/using29.C b/gcc/testsuite/g++.dg/template/using29.C new file mode 100644 index 000000000000..8726547efdb1 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using29.C @@ -0,0 +1,21 @@ +// PR c++/58047 + +template +struct print_arg { }; + +struct const_holder { + static const int CONSTANT = 42; +}; + +template +struct identity { + typedef T type; +}; + +template +struct test_case : public identity { + using typename identity::type; + print_arg printer; +}; + +template struct test_case;