diff options
author | Mark Mitchell <mark@codesourcery.com> | 2003-06-20 00:48:44 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2003-06-20 00:48:44 +0000 |
commit | 170b020fe4be4eadea27d389257778d952fb5a13 (patch) | |
tree | 18750127388f053e1dd83e7ae5f29fc9e9fe0bfb /gcc/cp | |
parent | 7a1d37e9102a1bbc34b4544161ddf283c667bc0b (diff) | |
download | gcc-170b020fe4be4eadea27d389257778d952fb5a13.zip gcc-170b020fe4be4eadea27d389257778d952fb5a13.tar.gz gcc-170b020fe4be4eadea27d389257778d952fb5a13.tar.bz2 |
re PR middle-end/11041 (ICE: const myclass &x = *x; (when operator*() defined))
PR c++/11041
* call.c (initialize_reference): Do not use cp_finish_decl to emit
temporary variables.
* cp-tree.h (static_aggregates): Declare.
(pushdecl_top_level_and_finish): Likewise.
* decl.c (pushdecl_top_level_1): New function.
(pushdecl_top_level): Use it.
(pushdecl_top_level_and_finish): New function.
(initialize_local_var): Remove redundant code.
(cp_finish_decl): Remove support for RESULT_DECLs. Don't check
building_stmt_tree.
* decl.h (static_aggregates): Remove.
* decl2.c (get_guard): Use pushdecl_top_level_and_finish.
* rtti.c (get_tinfo_decl): Use pushdecl_top_level_and_finish.
(tinfo_base_init): Likewise.
PR c++/11041
* g++.dg/init/ref7.C: New test.
From-SVN: r68236
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/cp/call.c | 30 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 7 | ||||
-rw-r--r-- | gcc/cp/decl.c | 57 | ||||
-rw-r--r-- | gcc/cp/decl.h | 6 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 3 | ||||
-rw-r--r-- | gcc/cp/rtti.c | 6 |
7 files changed, 87 insertions, 40 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ba1fb35..30e01f2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,21 @@ +2003-06-19 Mark Mitchell <mark@codesourcery.com> + + PR c++/11041 + * call.c (initialize_reference): Do not use cp_finish_decl to emit + temporary variables. + * cp-tree.h (static_aggregates): Declare. + (pushdecl_top_level_and_finish): Likewise. + * decl.c (pushdecl_top_level_1): New function. + (pushdecl_top_level): Use it. + (pushdecl_top_level_and_finish): New function. + (initialize_local_var): Remove redundant code. + (cp_finish_decl): Remove support for RESULT_DECLs. Don't check + building_stmt_tree. + * decl.h (static_aggregates): Remove. + * decl2.c (get_guard): Use pushdecl_top_level_and_finish. + * rtti.c (get_tinfo_decl): Use pushdecl_top_level_and_finish. + (tinfo_base_init): Likewise. + 2003-06-19 Matt Austern <austern@apple.com> PR c++/11228 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 589a789..9bc55be 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -6144,7 +6144,7 @@ initialize_reference (tree type, tree expr, tree decl) T t; const S& s = t; - we can extend the lifetime of the returnn value of the conversion + we can extend the lifetime of the return value of the conversion operator. */ my_friendly_assert (TREE_CODE (conv) == REF_BIND, 20030302); if (decl) @@ -6167,13 +6167,33 @@ initialize_reference (tree type, tree expr, tree decl) expr = convert_like (conv, expr); if (!real_non_cast_lvalue_p (expr)) { + tree init; + tree type; + /* Create the temporary variable. */ - var = make_temporary_var_for_ref_to_temp (decl, TREE_TYPE (expr)); - DECL_INITIAL (var) = expr; - cp_finish_decl (var, expr, NULL_TREE, - LOOKUP_ONLYCONVERTING|DIRECT_BIND); + type = TREE_TYPE (expr); + var = make_temporary_var_for_ref_to_temp (decl, type); + layout_decl (var, 0); + if (at_function_scope_p ()) + { + tree cleanup; + + add_decl_stmt (var); + cleanup = cxx_maybe_build_cleanup (var); + if (cleanup) + finish_decl_cleanup (var, cleanup); + } + else + { + rest_of_decl_compilation (var, NULL, /*toplev=*/1, at_eof); + if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) + static_aggregates = tree_cons (NULL_TREE, var, + static_aggregates); + } + init = build (INIT_EXPR, type, var, expr); /* Use its address to initialize the reference variable. */ expr = build_address (var); + expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr); } else /* Take the address of EXPR. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index d3d20e7..bfb7e0f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3263,6 +3263,12 @@ extern GTY(()) varray_type local_classes; extern int at_eof; +/* A list of namespace-scope objects which have constructors or + destructors which reside in the global scope. The decl is stored + in the TREE_VALUE slot and the initializer is stored in the + TREE_PURPOSE slot. */ +extern GTY(()) tree static_aggregates; + /* Functions called along with real static constructors and destructors. */ extern GTY(()) tree static_ctors; @@ -3631,6 +3637,7 @@ extern void clear_anon_tags (void); extern int decls_match (tree, tree); extern int duplicate_decls (tree, tree); extern tree pushdecl_top_level (tree); +extern tree pushdecl_top_level_and_finish (tree, tree); extern void pushdecl_class_level (tree); extern tree pushdecl_namespace_level (tree); extern tree push_using_decl (tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 4ec5c31..d025a6f 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4143,18 +4143,40 @@ pushdecl_namespace_level (tree x) POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); } -/* Like pushdecl, only it places X in the global scope if appropriate. */ +/* Like pushdecl, only it places X in the global scope if appropriate. + Calls cp_finish_decl to register the variable, initializing it with + *INIT, if INIT is non-NULL. */ -tree -pushdecl_top_level (tree x) +static tree +pushdecl_top_level_1 (tree x, tree *init) { timevar_push (TV_NAME_LOOKUP); push_to_top_level (); x = pushdecl_namespace_level (x); + if (init) + cp_finish_decl (x, *init, NULL_TREE, 0); pop_from_top_level (); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); } +/* Like pushdecl, only it places X in the global scope if appropriate. */ + +tree +pushdecl_top_level (tree x) +{ + return pushdecl_top_level_1 (x, NULL); +} + +/* Like pushdecl, only it places X in the global scope if + appropriate. Calls cp_finish_decl to register the variable, + initializing it with INIT. */ + +tree +pushdecl_top_level_and_finish (tree x, tree init) +{ + return pushdecl_top_level_1 (x, &init); +} + /* Make the declaration of X appear in CLASS scope. */ void @@ -7903,6 +7925,7 @@ static void initialize_local_var (tree decl, tree init) { tree type = TREE_TYPE (decl); + tree cleanup; my_friendly_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == RESULT_DECL, @@ -7952,17 +7975,9 @@ initialize_local_var (tree decl, tree init) } /* Generate a cleanup, if necessary. */ - if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) - { - tree cleanup; - - /* Compute the cleanup. */ - cleanup = cxx_maybe_build_cleanup (decl); - - /* Record the cleanup required for this declaration. */ - if (DECL_SIZE (decl) && cleanup) - finish_decl_cleanup (decl, cleanup); - } + cleanup = cxx_maybe_build_cleanup (decl); + if (DECL_SIZE (decl) && cleanup) + finish_decl_cleanup (decl, cleanup); } /* Finish processing of a declaration; @@ -7991,6 +8006,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) return; } + my_friendly_assert (TREE_CODE (decl) != RESULT_DECL, 20030619); + /* If a name was specified, get the string. */ if (global_scope_p (current_binding_level)) asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree); @@ -8031,8 +8048,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) if (processing_template_decl) { /* Add this declaration to the statement-tree. */ - if (at_function_scope_p () - && TREE_CODE (decl) != RESULT_DECL) + if (at_function_scope_p ()) add_decl_stmt (decl); if (init && DECL_INITIAL (decl)) @@ -8089,8 +8105,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec)); make_decl_rtl (decl, asmspec); } - else if (TREE_CODE (decl) == RESULT_DECL) - init = check_initializer (decl, init, flags); else if (TREE_CODE (decl) == VAR_DECL) { /* Only PODs can have thread-local storage. Other types may require @@ -8146,9 +8160,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) /* Add this declaration to the statement-tree. This needs to happen after the call to check_initializer so that the DECL_STMT for a reference temp is added before the DECL_STMT for the reference itself. */ - if (building_stmt_tree () - && at_function_scope_p () - && TREE_CODE (decl) != RESULT_DECL) + if (at_function_scope_p ()) add_decl_stmt (decl); if (TREE_CODE (decl) == VAR_DECL) @@ -8157,8 +8169,7 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) /* Output the assembler code and/or RTL code for variables and functions, unless the type is an undefined structure or union. If not, it will get done when the type is completed. */ - if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL - || TREE_CODE (decl) == RESULT_DECL) + if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL) { if (TREE_CODE (decl) == VAR_DECL) maybe_commonize_var (decl); diff --git a/gcc/cp/decl.h b/gcc/cp/decl.h index b942687..2a7a765 100644 --- a/gcc/cp/decl.h +++ b/gcc/cp/decl.h @@ -37,12 +37,6 @@ extern tree grokdeclarator (tree, tree, enum decl_context, int, tree*); or a chain or parameter decls here. */ extern GTY(()) tree last_function_parms; -/* A list of objects which have constructors or destructors - which reside in the global scope. The decl is stored in - the TREE_VALUE slot and the initializer is stored - in the TREE_PURPOSE slot. */ -extern GTY(()) tree static_aggregates; - #ifdef DEBUG_CP_BINDING_LEVELS /* Purely for debugging purposes. */ extern int debug_bindings_indentation; diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 1413f39..3fa4d74 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -1886,8 +1886,7 @@ get_guard (tree decl) DECL_ARTIFICIAL (guard) = 1; TREE_USED (guard) = 1; - pushdecl_top_level (guard); - cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0); + pushdecl_top_level_and_finish (guard, NULL_TREE); } return guard; } diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index ac117fa..1a29c1c 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -364,9 +364,8 @@ get_tinfo_decl (tree type) DECL_EXTERNAL (d) = 1; SET_DECL_ASSEMBLER_NAME (d, name); DECL_COMDAT (d) = 1; - cp_finish_decl (d, NULL_TREE, NULL_TREE, 0); - pushdecl_top_level (d); + pushdecl_top_level_and_finish (d, NULL_TREE); if (CLASS_TYPE_P (type)) CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d; @@ -770,8 +769,7 @@ tinfo_base_init (tree desc, tree target) SET_DECL_ASSEMBLER_NAME (name_decl, mangle_typeinfo_string_for_type (target)); DECL_INITIAL (name_decl) = name_string; - cp_finish_decl (name_decl, name_string, NULL_TREE, 0); - pushdecl_top_level (name_decl); + pushdecl_top_level_and_finish (name_decl, name_string); } vtable_ptr = TINFO_VTABLE_DECL (desc); |