mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-10 19:37:24 +08:00
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
This commit is contained in:
parent
e607534b43
commit
5dae1114bb
@ -1,3 +1,27 @@
|
||||
2003-01-17 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
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 <jason@redhat.com>
|
||||
|
||||
PR c++/8564
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -1,3 +1,13 @@
|
||||
2003-01-17 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
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 <rth@redhat.com>
|
||||
|
||||
* g++.dg/tls/init-2.C: Fix error matches for real this time.
|
||||
|
9
gcc/testsuite/g++.dg/parse/ctor1.C
Normal file
9
gcc/testsuite/g++.dg/parse/ctor1.C
Normal file
@ -0,0 +1,9 @@
|
||||
class L {
|
||||
public:
|
||||
L(int);
|
||||
};
|
||||
|
||||
class R {
|
||||
friend L::L(int);
|
||||
};
|
||||
|
14
gcc/testsuite/g++.dg/parse/qualified1.C
Normal file
14
gcc/testsuite/g++.dg/parse/qualified1.C
Normal file
@ -0,0 +1,14 @@
|
||||
struct A {};
|
||||
|
||||
struct B : public A
|
||||
{
|
||||
static void foo ();
|
||||
};
|
||||
|
||||
template <typename T> struct C
|
||||
{
|
||||
C() : f(B::foo) {}
|
||||
void (*f)();
|
||||
};
|
||||
|
||||
C<int> c;
|
8
gcc/testsuite/g++.dg/parse/typename3.C
Normal file
8
gcc/testsuite/g++.dg/parse/typename3.C
Normal file
@ -0,0 +1,8 @@
|
||||
template <typename T>
|
||||
struct D2 : public T::B {
|
||||
typedef typename T::X::Y Y;
|
||||
|
||||
void f () {
|
||||
Y::f ();
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue
Block a user