diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b025fa7e623847506f7633366a7042c03ca402a5..309738cdbbaa4b30a01a4b067dd08a997b3707b6 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2011-12-27 Fabien Chêne <fabien@gcc.gnu.org> + + PR c++/23211 + * name-lookup.c (do_class_using_decl): Use dependent_scope_p + instead of dependent_type_p, to check that a non-dependent + nested-name-specifier of a class-scope using declaration refers to + a base, even if the current scope is dependent. + * parser.c (cp_parser_using_declaration): Set + USING_DECL_TYPENAME_P to 1 if the DECL is not null. Re-indent a + 'else' close to the prior modification. + 2011-12-23 Jason Merrill <jason@redhat.com> PR c++/51507 diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index ceecdef3e8ddcf21ffbb517e1f0d54d82185f427..5734055b103aaf53e76cc4333296665602cb7faf 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -3217,7 +3217,7 @@ do_class_using_decl (tree scope, tree name) return NULL_TREE; } - scope_dependent_p = dependent_type_p (scope); + scope_dependent_p = dependent_scope_p (scope); name_dependent_p = (scope_dependent_p || (IDENTIFIER_TYPENAME_P (name) && dependent_type_p (TREE_TYPE (name)))); @@ -3242,9 +3242,9 @@ do_class_using_decl (tree scope, tree name) In general, we cannot check this constraint in a template because we do not know the entire set of base classes of the current - class type. However, if all of the base classes are - non-dependent, then we can avoid delaying the check until - instantiation. */ + class type. Morover, if SCOPE is dependent, it might match a + non-dependent base. */ + if (!scope_dependent_p) { base_kind b_kind; @@ -3270,7 +3270,7 @@ do_class_using_decl (tree scope, tree name) if (BASELINK_P (decl)) decl = BASELINK_FUNCTIONS (decl); } - } + } value = build_lang_decl (USING_DECL, name, NULL_TREE); USING_DECL_DECLS (value) = decl; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 51d04d46fc07e9176f64916f24a0364d4bb75db5..d4947e7c5d4513d056f7b6f58c80909e3cfd966f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -14971,12 +14971,12 @@ cp_parser_using_declaration (cp_parser* parser, /* Create the USING_DECL. */ decl = do_class_using_decl (parser->scope, identifier); - if (typename_p) + if (decl && typename_p) USING_DECL_TYPENAME_P (decl) = 1; if (check_for_bare_parameter_packs (decl)) return false; - else + else /* Add it to the list of members in this class. */ finish_member_declaration (decl); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index aba19e9a5ae5e5fb0101271677ef7fd4e38bba1a..732c7d1b18f9bb8e8c69ae64b78dcd3541918fb3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2011-12-27 Fabien Chêne <fabien@gcc.gnu.org> + + PR c++/23211 + * g++.dg/template/using18.C: New. + * g++.dg/template/using19.C: New. + * g++.dg/template/nested3.C: Remove dg-message at instantiation. + * g++.dg/template/crash13.C: Likewise. + 2011-12-28 Michael Meissner <meissner@linux.vnet.ibm.com> PR target/51623 diff --git a/gcc/testsuite/g++.dg/template/crash13.C b/gcc/testsuite/g++.dg/template/crash13.C index 917ddf09f10569a6acbe4a0d88439f8488f35bbd..e8e05945662a77f8d731294fdaebb1e6e726e9b2 100644 --- a/gcc/testsuite/g++.dg/template/crash13.C +++ b/gcc/testsuite/g++.dg/template/crash13.C @@ -15,4 +15,4 @@ template <typename T> struct C X::Y; // { dg-error "not a base type" } }; -C<void> c; // { dg-message "required" } +C<void> c; diff --git a/gcc/testsuite/g++.dg/template/nested3.C b/gcc/testsuite/g++.dg/template/nested3.C index 4544cc903b4033618ced7b178e6ed7bc80b5a9c6..5dcbf1961fabbc8c9c06914187b031a3b20c3971 100644 --- a/gcc/testsuite/g++.dg/template/nested3.C +++ b/gcc/testsuite/g++.dg/template/nested3.C @@ -24,7 +24,7 @@ class B { int main() { - B<char> objB; // { dg-message "required" } + B<char> objB; return 0; } diff --git a/gcc/testsuite/g++.dg/template/using18.C b/gcc/testsuite/g++.dg/template/using18.C new file mode 100644 index 0000000000000000000000000000000000000000..b4ef6df478c34ce742e4bfbaad776c82149a7c51 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using18.C @@ -0,0 +1,31 @@ +// PR c++/23211 +// { dg-do compile } + +template<class T> +struct foo +{ + typedef int jtype; + struct bar + { + using typename foo<T>::jtype; // { dg-error "not a base type" } + using foo<T>::jtype; // { dg-error "not a base type" } + }; +}; + +template <class T> +struct A : T +{ + using T::i; + using typename T::type; +}; + +struct B1 {}; +template <class T> struct B2 {}; + +template <class T> +struct C : B1, B2<T> +{ + using B1::x; // { dg-error "no member" } + using B2<T>::y; + using typename B2<T>::type; +}; diff --git a/gcc/testsuite/g++.dg/template/using19.C b/gcc/testsuite/g++.dg/template/using19.C new file mode 100644 index 0000000000000000000000000000000000000000..dc89f92ef0e8b97e34143b14bebf4fe9ab129570 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/using19.C @@ -0,0 +1,12 @@ +// PR c++/23211 +// { dg-do compile } + +struct A { int x; }; + +template <class T> +struct B: A +{ + using T::x; +}; + +B<A> b;