From: Jason Merrill Date: Fri, 3 Apr 2009 17:31:38 +0000 (-0400) Subject: revert: re PR c++/9634 ([DR224] Injected class name as qualifier should not make... X-Git-Tag: releases/gcc-4.3.4~244 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a5d05a6503b127517c33387ea242bbe1974524a2;p=thirdparty%2Fgcc.git revert: re PR c++/9634 ([DR224] Injected class name as qualifier should not make the name dependent) Revert: PR c++/9634 PR c++/29469 PR c++/29607 Implement DR 224. * decl.c (make_typename_type): Do look inside currently open classes. * parser.c (cp_parser_lookup_name): Likewise. (cp_parser_template_name): Likewise. * pt.c (dependent_scope_p): New function. * cp-tree.h: Declare it. * class.c (currently_open_class): Return fast if T isn't a class. From-SVN: r145510 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e7a49cc79d4f..487da5a513e1 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -18,18 +18,6 @@ rest of the specialization when begin_specialization returns false. -2009-03-04 Jason Merrill - - PR c++/9634 - PR c++/29469 - PR c++/29607 - * decl.c (make_typename_type): Do look inside currently open classes. - * parser.c (cp_parser_lookup_name): Likewise. - (cp_parser_template_name): Likewise. - * pt.c (dependent_scope_p): New function. - * cp-tree.h: Declare it. - * class.c (currently_open_class): Return fast if T isn't a class. - 2009-02-20 Jason Merrill PR c++/39225 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 6c5e488d8558..fe722f4ef335 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5688,9 +5688,6 @@ currently_open_class (tree t) { int i; - if (!CLASS_TYPE_P (t)) - return false; - /* We start looking from 1 because entry 0 is from global scope, and has no type. */ for (i = current_class_depth; i > 0; --i) diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ec9bcbbab7c5..0872280a39b6 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4460,7 +4460,6 @@ extern struct tinst_level *current_instantiation(void); extern tree maybe_get_template_decl_from_type_decl (tree); extern int processing_template_parmlist; extern bool dependent_type_p (tree); -extern bool dependent_scope_p (tree); extern bool any_dependent_template_arguments_p (const_tree); extern bool dependent_template_p (tree); extern bool dependent_template_id_p (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b36c0769ea2c..6a659533ea54 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2978,6 +2978,12 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); gcc_assert (TYPE_P (context)); + /* When the CONTEXT is a dependent type, NAME could refer to a + dependent base class of CONTEXT. So we cannot peek inside it, + even if CONTEXT is a currently open scope. */ + if (dependent_type_p (context)) + return build_typename_type (context, name, fullname, tag_type); + if (!IS_AGGR_TYPE (context)) { if (complain & tf_error) @@ -2985,23 +2991,11 @@ make_typename_type (tree context, tree name, enum tag_types tag_type, return error_mark_node; } - /* When the CONTEXT is a dependent type, NAME could refer to a - dependent base class of CONTEXT. But look inside it anyway - if CONTEXT is a currently open scope, in case it refers to a - member of the current instantiation or a non-dependent base; - lookup will stop when we hit a dependent base. */ - if (!dependent_scope_p (context)) - /* We should only set WANT_TYPE when we're a nested typename type. - Then we can give better diagnostics if we find a non-type. */ - t = lookup_field (context, name, 0, /*want_type=*/true); - else - t = NULL_TREE; - - if (!t && dependent_type_p (context)) - return build_typename_type (context, name, fullname, tag_type); - want_template = TREE_CODE (fullname) == TEMPLATE_ID_EXPR; + /* We should only set WANT_TYPE when we're a nested typename type. + Then we can give better diagnostics if we find a non-type. */ + t = lookup_field (context, name, 0, /*want_type=*/true); if (!t) { if (complain & tf_error) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8247c9cc0d8f..d4ae9b380b9c 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -9953,7 +9953,7 @@ cp_parser_template_name (cp_parser* parser, && !template_keyword_p && parser->scope && TYPE_P (parser->scope) && check_dependency_p - && dependent_scope_p (parser->scope) + && dependent_type_p (parser->scope) /* Do not do this for dtors (or ctors), since they never need the template keyword before their name. */ && !constructor_name_p (identifier, parser->scope)) @@ -16225,11 +16225,35 @@ cp_parser_lookup_name (cp_parser *parser, tree name, cannot look up the name if the scope is not a class type; it might, for example, be a template type parameter. */ dependent_p = (TYPE_P (parser->scope) - && dependent_scope_p (parser->scope)); + && !(parser->in_declarator_p + && currently_open_class (parser->scope)) + && dependent_type_p (parser->scope)); if ((check_dependency || !CLASS_TYPE_P (parser->scope)) - && dependent_p) - /* Defer lookup. */ - decl = error_mark_node; + && dependent_p) + { + if (tag_type) + { + tree type; + + /* The resolution to Core Issue 180 says that `struct + A::B' should be considered a type-name, even if `A' + is dependent. */ + type = make_typename_type (parser->scope, name, tag_type, + /*complain=*/tf_error); + decl = TYPE_NAME (type); + } + else if (is_template + && (cp_parser_next_token_ends_template_argument_p (parser) + || cp_lexer_next_token_is (parser->lexer, + CPP_CLOSE_PAREN))) + decl = make_unbound_class_template (parser->scope, + name, NULL_TREE, + /*complain=*/tf_error); + else + decl = build_qualified_name (/*type=*/NULL_TREE, + parser->scope, name, + is_template); + } else { tree pushed_scope = NULL_TREE; @@ -16250,42 +16274,14 @@ cp_parser_lookup_name (cp_parser *parser, tree name, /*complain=*/true); /* If we have a single function from a using decl, pull it out. */ - if (TREE_CODE (decl) == OVERLOAD + if (decl + && TREE_CODE (decl) == OVERLOAD && !really_overloaded_fn (decl)) decl = OVL_FUNCTION (decl); if (pushed_scope) pop_scope (pushed_scope); } - - /* If the scope is a dependent type and either we deferred lookup or - we did lookup but didn't find the name, rememeber the name. */ - if (decl == error_mark_node && TYPE_P (parser->scope) - && dependent_type_p (parser->scope)) - { - if (tag_type) - { - tree type; - - /* The resolution to Core Issue 180 says that `struct - A::B' should be considered a type-name, even if `A' - is dependent. */ - type = make_typename_type (parser->scope, name, tag_type, - /*complain=*/tf_error); - decl = TYPE_NAME (type); - } - else if (is_template - && (cp_parser_next_token_ends_template_argument_p (parser) - || cp_lexer_next_token_is (parser->lexer, - CPP_CLOSE_PAREN))) - decl = make_unbound_class_template (parser->scope, - name, NULL_TREE, - /*complain=*/tf_error); - else - decl = build_qualified_name (/*type=*/NULL_TREE, - parser->scope, name, - is_template); - } parser->qualifying_scope = parser->scope; parser->object_scope = NULL_TREE; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 81a087919fca..7eaf68b18d89 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -15644,16 +15644,6 @@ dependent_type_p (tree type) return TYPE_DEPENDENT_P (type); } -/* Returns TRUE if SCOPE is a dependent scope, in which we can't do any - lookup. In other words, a dependent type that is not the current - instantiation. */ - -bool -dependent_scope_p (tree scope) -{ - return dependent_type_p (scope) && !currently_open_class (scope); -} - /* Returns TRUE if EXPRESSION is dependent, according to CRITERION. */ static bool @@ -15675,7 +15665,7 @@ dependent_scope_ref_p (tree expression, bool criterion (tree)) An id-expression is type-dependent if it contains a nested-name-specifier that contains a class-name that names a dependent type. */ - /* The suggested resolution to Core Issue 224 implies that if the + /* The suggested resolution to Core Issue 2 implies that if the qualifying type is the current class, then we must peek inside it. */ if (DECL_P (name) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index db41f9e25ad1..91d19668de88 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -64,14 +64,6 @@ PR fortran/39292 * gfortran.dg/initialization_22.f90: New test. -2009-03-04 Jason Merrill - Giovanni Bajo - - PR c++/9634 - PR c++/29469 - PR c++/29607 - * g++.dg/template/dependent-name5.C: New test. - 2009-02-26 Uros Bizjak Backport from mainline: diff --git a/gcc/testsuite/g++.dg/template/dependent-name5.C b/gcc/testsuite/g++.dg/template/dependent-name5.C deleted file mode 100644 index 681060c7002e..000000000000 --- a/gcc/testsuite/g++.dg/template/dependent-name5.C +++ /dev/null @@ -1,45 +0,0 @@ -// PR c++/9634, c++/29469, c++/29607 -// Contributed by: Giovanni Bajo -// DR224: Make sure that a name is *truly* semantically dependent. - -struct D { - typedef int K; -}; - -template -struct A -{ - typedef int Bar; - - template - struct N {}; - - typedef Bar type1; - typedef A::Bar type2; - typedef A::Bar type3; - typedef A::Bar type4; // { dg-error "" } - typedef typename A::Bar type5; - - typedef N type6; - typedef A::N type7; - typedef A::N type8; - typedef A::template N type9; // { dg-error "" } - typedef typename A::template N type10; - - typedef D Bar2; - struct N2 { typedef int K; }; - - // Check that A::N2 is still considered dependent (because it - // could be specialized), while A::Bar2 (being just ::D) is not. - typedef A::Bar2 type11; - typedef type11::K k3; - - typedef A::N2 type12; - typedef typename type12::K k2; - typedef type12::K k1; // { dg-error "" } - - // Check that A::Bar2 is not considered dependent even if we use - // the typename keyword. - typedef typename A::Bar2 type13; - typedef type13::K k4; -};