diff options
author | Nathan Sidwell <nathan@codesourcery.com> | 2005-08-11 09:23:57 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2005-08-11 09:23:57 +0000 |
commit | 6a0007046e65103e31c66bc0ef0d28d28e89d813 (patch) | |
tree | 4c03d748fb74ca597e759c18eab345d5d1958165 /gcc/cp/name-lookup.c | |
parent | cac329963a81d95f7f04ece46bbc07786e954e40 (diff) | |
download | gcc-6a0007046e65103e31c66bc0ef0d28d28e89d813.zip gcc-6a0007046e65103e31c66bc0ef0d28d28e89d813.tar.gz gcc-6a0007046e65103e31c66bc0ef0d28d28e89d813.tar.bz2 |
re PR c++/23219 (ICE: Segmentation fault in decl_namespace_context)
cp:
PR c++/23219
* name-lookup.c (pushtag): Process the template type before
altering the identifier lookup fields. Remove unreachable code
creating an empty stub decl.
testsuite:
PR c++/23219
* g++.dg/parse/crash28.C: New.
From-SVN: r102982
Diffstat (limited to 'gcc/cp/name-lookup.c')
-rw-r--r-- | gcc/cp/name-lookup.c | 182 |
1 files changed, 86 insertions, 96 deletions
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index a03b648..79a6552 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4626,6 +4626,7 @@ tree pushtag (tree name, tree type, tag_scope scope) { struct cp_binding_level *b; + tree decl; timevar_push (TV_NAME_LOOKUP); b = current_binding_level; @@ -4647,114 +4648,103 @@ pushtag (tree name, tree type, tag_scope scope) || COMPLETE_TYPE_P (b->this_entity)))) b = b->level_chain; - if (name) + gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); + + /* Do C++ gratuitous typedefing. */ + if (IDENTIFIER_TYPE_VALUE (name) != type) { - /* Do C++ gratuitous typedefing. */ - if (IDENTIFIER_TYPE_VALUE (name) != type) - { - tree d = NULL_TREE; - int in_class = 0; - tree context = TYPE_CONTEXT (type); - - if (! context) - { - tree cs = current_scope (); - - if (scope == ts_current) - context = cs; - else if (cs != NULL_TREE && TYPE_P (cs)) - /* When declaring a friend class of a local class, we want - to inject the newly named class into the scope - containing the local class, not the namespace scope. */ - context = decl_function_context (get_type_decl (cs)); - } - if (!context) - context = current_namespace; - - if (b->kind == sk_class - || (b->kind == sk_template_parms - && b->level_chain->kind == sk_class)) - in_class = 1; + tree tdef; + int in_class = 0; + tree context = TYPE_CONTEXT (type); - if (current_lang_name == lang_name_java) - TYPE_FOR_JAVA (type) = 1; + if (! context) + { + tree cs = current_scope (); + + if (scope == ts_current) + context = cs; + else if (cs != NULL_TREE && TYPE_P (cs)) + /* When declaring a friend class of a local class, we want + to inject the newly named class into the scope + containing the local class, not the namespace + scope. */ + context = decl_function_context (get_type_decl (cs)); + } + if (!context) + context = current_namespace; - d = create_implicit_typedef (name, type); - DECL_CONTEXT (d) = FROB_CONTEXT (context); - if (scope == ts_within_enclosing_non_class) - { - /* This is a friend. Make this TYPE_DECL node hidden from - ordinary name lookup. Its corresponding TEMPLATE_DECL - will be marked in push_template_decl_real. */ - retrofit_lang_decl (d); - DECL_ANTICIPATED (d) = 1; - DECL_FRIEND_P (d) = 1; - } + if (b->kind == sk_class + || (b->kind == sk_template_parms + && b->level_chain->kind == sk_class)) + in_class = 1; - if (! in_class) - set_identifier_type_value_with_scope (name, d, b); + if (current_lang_name == lang_name_java) + TYPE_FOR_JAVA (type) = 1; - d = maybe_process_template_type_declaration - (type, scope == ts_within_enclosing_non_class, b); - if (d == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); - - if (b->kind == sk_class) - { - if (!PROCESSING_REAL_TEMPLATE_DECL_P ()) - /* Put this TYPE_DECL on the TYPE_FIELDS list for the - class. But if it's a member template class, we - want the TEMPLATE_DECL, not the TYPE_DECL, so this - is done later. */ - finish_member_declaration (d); - else - pushdecl_class_level (d); - } - else if (b->kind != sk_template_parms) - d = pushdecl_with_scope (d, b); - - TYPE_CONTEXT (type) = DECL_CONTEXT (d); - - /* If this is a local class, keep track of it. We need this - information for name-mangling, and so that it is possible to find - all function definitions in a translation unit in a convenient - way. (It's otherwise tricky to find a member function definition - it's only pointed to from within a local class.) */ - if (TYPE_CONTEXT (type) - && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL) - VEC_safe_push (tree, gc, local_classes, type); - } - if (b->kind == sk_class - && !COMPLETE_TYPE_P (current_class_type)) + tdef = create_implicit_typedef (name, type); + DECL_CONTEXT (tdef) = FROB_CONTEXT (context); + if (scope == ts_within_enclosing_non_class) { - maybe_add_class_template_decl_list (current_class_type, - type, /*friend_p=*/0); + /* This is a friend. Make this TYPE_DECL node hidden from + ordinary name lookup. Its corresponding TEMPLATE_DECL + will be marked in push_template_decl_real. */ + retrofit_lang_decl (tdef); + DECL_ANTICIPATED (tdef) = 1; + DECL_FRIEND_P (tdef) = 1; + } - if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL) - CLASSTYPE_NESTED_UTDS (current_class_type) - = binding_table_new (SCOPE_DEFAULT_HT_SIZE); + decl = maybe_process_template_type_declaration + (type, scope == ts_within_enclosing_non_class, b); + if (decl == error_mark_node) + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + + if (! in_class) + set_identifier_type_value_with_scope (name, tdef, b); - binding_table_insert - (CLASSTYPE_NESTED_UTDS (current_class_type), name, type); + if (b->kind == sk_class) + { + if (!PROCESSING_REAL_TEMPLATE_DECL_P ()) + /* Put this TYPE_DECL on the TYPE_FIELDS list for the + class. But if it's a member template class, we want + the TEMPLATE_DECL, not the TYPE_DECL, so this is done + later. */ + finish_member_declaration (decl); + else + pushdecl_class_level (decl); } + else if (b->kind != sk_template_parms) + decl = pushdecl_with_scope (decl, b); + + TYPE_CONTEXT (type) = DECL_CONTEXT (decl); + + /* If this is a local class, keep track of it. We need this + information for name-mangling, and so that it is possible to + find all function definitions in a translation unit in a + convenient way. (It's otherwise tricky to find a member + function definition it's only pointed to from within a local + class.) */ + if (TYPE_CONTEXT (type) + && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL) + VEC_safe_push (tree, gc, local_classes, type); } - - if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) - /* Use the canonical TYPE_DECL for this node. */ - TYPE_STUB_DECL (type) = TYPE_NAME (type); - else + if (b->kind == sk_class + && !COMPLETE_TYPE_P (current_class_type)) { - /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE - will be the tagged type we just added to the current - binding level. This fake NULL-named TYPE_DECL node helps - dwarfout.c to know when it needs to output a - representation of a tagged type, and it also gives us a - convenient place to record the "scope start" address for - the tagged type. */ - - tree d = build_decl (TYPE_DECL, NULL_TREE, type); - TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b); + maybe_add_class_template_decl_list (current_class_type, + type, /*friend_p=*/0); + + if (CLASSTYPE_NESTED_UTDS (current_class_type) == NULL) + CLASSTYPE_NESTED_UTDS (current_class_type) + = binding_table_new (SCOPE_DEFAULT_HT_SIZE); + + binding_table_insert + (CLASSTYPE_NESTED_UTDS (current_class_type), name, type); } + + decl = TYPE_NAME (type); + gcc_assert (TREE_CODE (decl) == TYPE_DECL); + TYPE_STUB_DECL (type) = decl; + POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type); } |