From 5dae1114bb636a814b154c3c47ff6ad149bc81de Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 17 Jan 2003 20:14:44 +0000 Subject: [PATCH] re PR c++/9294 ([new parser] parser enters infinite loop) PR c++/9294 * cp-tree.def (BASELINK): Make it class 'x', not class 'e'. * cp-tree.h (BASELINK_BINFO): Adjust. (BASELINK_FUNCTIONS): Likewise. (BASELINK_ACCESS_BINFO): Likewise. (tree_baselink): New structure. (cp_tree_node_structure_enum): Add TS_CP_BASELINK. (lang_tree_node): Add baselink. * decl.c (cp_tree_node_structure): Add BASELINK case. * search.c (build_baselink): Adjust. * tree.c (cp_walk_subtrees): Add BASELINK case. Remove BASELINK_P test from TREE_LIST case. PR c++/9272 * parser.c (cp_parser_constructor_declarator_p): Do not assume that a constructor cannot be declared outside of its own class. * parser.c (cp_parser_resolve_typename_type): If the scope cannot be resolved, neither can the qualified name. * rtti.c (get_pseudo_ti_desc): Fix thinko. PR c++/9272 * g++.dg/parse/ctor1.C: New test. PR c++/9294: * g++.dg/parse/qualified1.C: New test. * g++.dg/parse/typename3.C: New test. From-SVN: r61456 --- gcc/cp/ChangeLog | 24 +++++++++++ gcc/cp/cp-tree.def | 2 +- gcc/cp/cp-tree.h | 16 +++++-- gcc/cp/decl.c | 1 + gcc/cp/parser.c | 56 +++++++++++-------------- gcc/cp/rtti.c | 11 +++-- gcc/cp/search.c | 4 +- gcc/cp/tree.c | 5 +-- gcc/testsuite/ChangeLog | 10 +++++ gcc/testsuite/g++.dg/parse/ctor1.C | 9 ++++ gcc/testsuite/g++.dg/parse/qualified1.C | 14 +++++++ gcc/testsuite/g++.dg/parse/typename3.C | 8 ++++ 12 files changed, 116 insertions(+), 44 deletions(-) create mode 100644 gcc/testsuite/g++.dg/parse/ctor1.C create mode 100644 gcc/testsuite/g++.dg/parse/qualified1.C create mode 100644 gcc/testsuite/g++.dg/parse/typename3.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d50b3d629ab9..36890c35ff03 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,27 @@ +2003-01-17 Mark Mitchell + + PR c++/9294 + * cp-tree.def (BASELINK): Make it class 'x', not class 'e'. + * cp-tree.h (BASELINK_BINFO): Adjust. + (BASELINK_FUNCTIONS): Likewise. + (BASELINK_ACCESS_BINFO): Likewise. + (tree_baselink): New structure. + (cp_tree_node_structure_enum): Add TS_CP_BASELINK. + (lang_tree_node): Add baselink. + * decl.c (cp_tree_node_structure): Add BASELINK case. + * search.c (build_baselink): Adjust. + * tree.c (cp_walk_subtrees): Add BASELINK case. Remove BASELINK_P + test from TREE_LIST case. + + PR c++/9272 + * parser.c (cp_parser_constructor_declarator_p): Do not assume + that a constructor cannot be declared outside of its own class. + + * parser.c (cp_parser_resolve_typename_type): If the scope cannot + be resolved, neither can the qualified name. + + * rtti.c (get_pseudo_ti_desc): Fix thinko. + 2003-01-16 Jason Merrill PR c++/8564 diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def index caec9cdfe76c..f621844e3505 100644 --- a/gcc/cp/cp-tree.def +++ b/gcc/cp/cp-tree.def @@ -105,7 +105,7 @@ DEFTREECODE (ALIAS_DECL, "alias_decl", 'd', 0) the type of the expression. This type is either a FUNCTION_TYPE, METHOD_TYPE, or `unknown_type_node' indicating that the function is overloaded. */ -DEFTREECODE (BASELINK, "baselink", 'e', 3) +DEFTREECODE (BASELINK, "baselink", 'x', 3) /* Template definition. The following fields have the specified uses, although there are other macros in cp-tree.h that should be used for diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 4b29211ca0ea..57f0621544a7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -373,16 +373,16 @@ struct tree_overload GTY(()) (TREE_CODE (NODE) == BASELINK) /* The BINFO indicating the base from which the BASELINK_FUNCTIONS came. */ #define BASELINK_BINFO(NODE) \ - (TREE_OPERAND (BASELINK_CHECK (NODE), 0)) + (((struct tree_baselink*) BASELINK_CHECK (NODE))->binfo) /* The functions referred to by the BASELINK; either a FUNCTION_DECL, a TEMPLATE_DECL, an OVERLOAD, or a TEMPLATE_ID_EXPR. */ #define BASELINK_FUNCTIONS(NODE) \ - (TREE_OPERAND (BASELINK_CHECK (NODE), 1)) + (((struct tree_baselink*) BASELINK_CHECK (NODE))->functions) /* The BINFO in which the search for the functions indicated by this baselink began. This base is used to determine the accessibility of functions selected by overload resolution. */ #define BASELINK_ACCESS_BINFO(NODE) \ - (TREE_OPERAND (BASELINK_CHECK (NODE), 2)) + (((struct tree_baselink*) BASELINK_CHECK (NODE))->access_binfo) /* For a type-conversion operator, the BASELINK_OPTYPE indicates the type to which the conversion should occur. This value is important if the BASELINK_FUNCTIONS include a template conversion operator -- @@ -391,6 +391,14 @@ struct tree_overload GTY(()) #define BASELINK_OPTYPE(NODE) \ (TREE_CHAIN (BASELINK_CHECK (NODE))) +struct tree_baselink GTY(()) +{ + struct tree_common common; + tree binfo; + tree functions; + tree access_binfo; +}; + #define WRAPPER_ZC(NODE) (((struct tree_wrapper*)WRAPPER_CHECK (NODE))->z_c) struct tree_wrapper GTY(()) @@ -520,6 +528,7 @@ enum cp_tree_node_structure_enum { TS_CP_PTRMEM, TS_CP_BINDING, TS_CP_OVERLOAD, + TS_CP_BASELINK, TS_CP_WRAPPER, TS_CP_SRCLOC, TS_CP_DEFAULT_ARG, @@ -537,6 +546,7 @@ union lang_tree_node GTY((desc ("cp_tree_node_structure (&%h)"), struct ptrmem_cst GTY ((tag ("TS_CP_PTRMEM"))) ptrmem; struct tree_binding GTY ((tag ("TS_CP_BINDING"))) binding; struct tree_overload GTY ((tag ("TS_CP_OVERLOAD"))) overload; + struct tree_baselink GTY ((tag ("TS_CP_BASELINK"))) baselink; struct tree_wrapper GTY ((tag ("TS_CP_WRAPPER"))) wrapper; struct tree_srcloc GTY ((tag ("TS_CP_SRCLOC"))) srcloc; struct tree_default_arg GTY ((tag ("TS_CP_DEFAULT_ARG"))) default_arg; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 4f3d9ed0c18f..f494ab3ee7e2 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -14481,6 +14481,7 @@ cp_tree_node_structure (union lang_tree_node * t) case OVERLOAD: return TS_CP_OVERLOAD; case TEMPLATE_PARM_INDEX: return TS_CP_TPI; case PTRMEM_CST: return TS_CP_PTRMEM; + case BASELINK: return TS_CP_BASELINK; case WRAPPER: return TS_CP_WRAPPER; case SRCLOC: return TS_CP_SRCLOC; default: return TS_CP_GENERIC; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 75d7a6456de5..412678c11a50 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13619,7 +13619,7 @@ cp_parser_resolve_typename_type (parser, type) 20010702); scope = TYPE_CONTEXT (type); - name = DECL_NAME (TYPE_NAME (type)); + name = TYPE_IDENTIFIER (type); /* If the SCOPE is itself a TYPENAME_TYPE, then we need to resolve it first before we can figure out what NAME refers to. */ @@ -13627,7 +13627,7 @@ cp_parser_resolve_typename_type (parser, type) scope = cp_parser_resolve_typename_type (parser, scope); /* If we don't know what SCOPE refers to, then we cannot resolve the TYPENAME_TYPE. */ - if (scope == error_mark_node) + if (scope == error_mark_node || TREE_CODE (scope) == TYPENAME_TYPE) return error_mark_node; /* If the SCOPE is a template type parameter, we have no way of resolving the name. */ @@ -14001,39 +14001,31 @@ cp_parser_constructor_declarator_p (cp_parser *parser, bool friend_p) && cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS) && !cp_parser_storage_class_specifier_opt (parser)) { - if (current_class_type - && !same_type_p (current_class_type, TREE_TYPE (type_decl))) - /* The constructor for one class cannot be declared inside - another. */ - constructor_p = false; + tree type; + + /* Names appearing in the type-specifier should be looked up + in the scope of the class. */ + if (current_class_type) + type = NULL_TREE; else { - tree type; - - /* Names appearing in the type-specifier should be looked up - in the scope of the class. */ - if (current_class_type) - type = NULL_TREE; - else - { - type = TREE_TYPE (type_decl); - if (TREE_CODE (type) == TYPENAME_TYPE) - type = cp_parser_resolve_typename_type (parser, type); - push_scope (type); - } - /* Look for the type-specifier. */ - cp_parser_type_specifier (parser, - CP_PARSER_FLAGS_NONE, - /*is_friend=*/false, - /*is_declarator=*/true, - /*declares_class_or_enum=*/NULL, - /*is_cv_qualifier=*/NULL); - /* Leave the scope of the class. */ - if (type) - pop_scope (type); - - constructor_p = !cp_parser_error_occurred (parser); + type = TREE_TYPE (type_decl); + if (TREE_CODE (type) == TYPENAME_TYPE) + type = cp_parser_resolve_typename_type (parser, type); + push_scope (type); } + /* Look for the type-specifier. */ + cp_parser_type_specifier (parser, + CP_PARSER_FLAGS_NONE, + /*is_friend=*/false, + /*is_declarator=*/true, + /*declares_class_or_enum=*/NULL, + /*is_cv_qualifier=*/NULL); + /* Leave the scope of the class. */ + if (type) + pop_scope (type); + + constructor_p = !cp_parser_error_occurred (parser); } } else diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 0b688051f9f4..e222d25c8764 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1216,9 +1216,14 @@ get_pseudo_ti_desc (tree type) if (var_desc) return var_desc; - /* Add number of bases and trailing array of - base_class_type_info. */ - array_domain = build_index_type (size_int (num_bases)); + /* Create the array of __base_class_type_info entries. + G++ 3.2 allocated an array that had one too many + entries, and then filled that extra entries with + zeros. */ + if (abi_version_at_least (2)) + array_domain = build_index_type (size_int (num_bases - 1)); + else + array_domain = build_index_type (size_int (num_bases)); base_array = build_array_type (base_desc_type_node, array_domain); diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 29ee667d1fbd..cab3bbb9cabd 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1385,8 +1385,8 @@ build_baselink (tree binfo, tree access_binfo, tree functions, tree optype) my_friendly_assert (!optype || TYPE_P (optype), 20020730); my_friendly_assert (TREE_TYPE (functions), 20020805); - baselink = build (BASELINK, TREE_TYPE (functions), NULL_TREE, - NULL_TREE, NULL_TREE); + baselink = make_node (BASELINK); + TREE_TYPE (baselink) = TREE_TYPE (functions); BASELINK_BINFO (baselink) = binfo; BASELINK_ACCESS_BINFO (baselink) = access_binfo; BASELINK_FUNCTIONS (baselink) = functions; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index a3b6ff14a4f4..0f60b91ca5ff 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2161,6 +2161,7 @@ cp_walk_subtrees (tp, walk_subtrees_p, func, data, htab) case TEMPLATE_TYPE_PARM: case TYPENAME_TYPE: case TYPEOF_TYPE: + case BASELINK: /* None of thse have subtrees other than those already walked above. */ *walk_subtrees_p = 0; @@ -2172,9 +2173,7 @@ cp_walk_subtrees (tp, walk_subtrees_p, func, data, htab) break; case TREE_LIST: - /* A BASELINK_P's TREE_PURPOSE is a BINFO, and hence circular. */ - if (!BASELINK_P (*tp)) - WALK_SUBTREE (TREE_PURPOSE (*tp)); + WALK_SUBTREE (TREE_PURPOSE (*tp)); break; case OVERLOAD: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7157141d99cf..82c0f557a850 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2003-01-17 Mark Mitchell + + PR c++/9272 + * g++.dg/parse/ctor1.C: New test. + + PR c++/9294: + * g++.dg/parse/qualified1.C: New test. + + * g++.dg/parse/typename3.C: New test. + 2003-01-16 Richard Henderson * g++.dg/tls/init-2.C: Fix error matches for real this time. diff --git a/gcc/testsuite/g++.dg/parse/ctor1.C b/gcc/testsuite/g++.dg/parse/ctor1.C new file mode 100644 index 000000000000..38428842c649 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/ctor1.C @@ -0,0 +1,9 @@ +class L { +public: + L(int); +}; + +class R { + friend L::L(int); +}; + diff --git a/gcc/testsuite/g++.dg/parse/qualified1.C b/gcc/testsuite/g++.dg/parse/qualified1.C new file mode 100644 index 000000000000..6dfb87e177ca --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/qualified1.C @@ -0,0 +1,14 @@ +struct A {}; + +struct B : public A +{ + static void foo (); +}; + +template struct C +{ + C() : f(B::foo) {} + void (*f)(); +}; + +C c; diff --git a/gcc/testsuite/g++.dg/parse/typename3.C b/gcc/testsuite/g++.dg/parse/typename3.C new file mode 100644 index 000000000000..ce6ecbef87a1 --- /dev/null +++ b/gcc/testsuite/g++.dg/parse/typename3.C @@ -0,0 +1,8 @@ +template +struct D2 : public T::B { + typedef typename T::X::Y Y; + + void f () { + Y::f (); + } +}; -- 2.43.5