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
This commit is contained in:
Mark Mitchell 2003-06-20 00:48:44 +00:00 committed by Mark Mitchell
parent 7a1d37e910
commit 170b020fe4
9 changed files with 103 additions and 42 deletions

View File

@ -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> 2003-06-19 Matt Austern <austern@apple.com>
PR c++/11228 PR c++/11228

View File

@ -6144,7 +6144,7 @@ initialize_reference (tree type, tree expr, tree decl)
T t; T t;
const S& s = 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. */ operator. */
my_friendly_assert (TREE_CODE (conv) == REF_BIND, 20030302); my_friendly_assert (TREE_CODE (conv) == REF_BIND, 20030302);
if (decl) if (decl)
@ -6167,13 +6167,33 @@ initialize_reference (tree type, tree expr, tree decl)
expr = convert_like (conv, expr); expr = convert_like (conv, expr);
if (!real_non_cast_lvalue_p (expr)) if (!real_non_cast_lvalue_p (expr))
{ {
tree init;
tree type;
/* Create the temporary variable. */ /* Create the temporary variable. */
var = make_temporary_var_for_ref_to_temp (decl, TREE_TYPE (expr)); type = TREE_TYPE (expr);
DECL_INITIAL (var) = expr; var = make_temporary_var_for_ref_to_temp (decl, type);
cp_finish_decl (var, expr, NULL_TREE, layout_decl (var, 0);
LOOKUP_ONLYCONVERTING|DIRECT_BIND); 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. */ /* Use its address to initialize the reference variable. */
expr = build_address (var); expr = build_address (var);
expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
} }
else else
/* Take the address of EXPR. */ /* Take the address of EXPR. */

View File

@ -3263,6 +3263,12 @@ extern GTY(()) varray_type local_classes;
extern int at_eof; 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. */ /* Functions called along with real static constructors and destructors. */
extern GTY(()) tree static_ctors; extern GTY(()) tree static_ctors;
@ -3631,6 +3637,7 @@ extern void clear_anon_tags (void);
extern int decls_match (tree, tree); extern int decls_match (tree, tree);
extern int duplicate_decls (tree, tree); extern int duplicate_decls (tree, tree);
extern tree pushdecl_top_level (tree); extern tree pushdecl_top_level (tree);
extern tree pushdecl_top_level_and_finish (tree, tree);
extern void pushdecl_class_level (tree); extern void pushdecl_class_level (tree);
extern tree pushdecl_namespace_level (tree); extern tree pushdecl_namespace_level (tree);
extern tree push_using_decl (tree, tree); extern tree push_using_decl (tree, tree);

View File

@ -4143,16 +4143,38 @@ pushdecl_namespace_level (tree x)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
} }
/* 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. */
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. */ /* Like pushdecl, only it places X in the global scope if appropriate. */
tree tree
pushdecl_top_level (tree x) pushdecl_top_level (tree x)
{ {
timevar_push (TV_NAME_LOOKUP); return pushdecl_top_level_1 (x, NULL);
push_to_top_level (); }
x = pushdecl_namespace_level (x);
pop_from_top_level (); /* Like pushdecl, only it places X in the global scope if
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); 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. */ /* Make the declaration of X appear in CLASS scope. */
@ -7903,6 +7925,7 @@ static void
initialize_local_var (tree decl, tree init) initialize_local_var (tree decl, tree init)
{ {
tree type = TREE_TYPE (decl); tree type = TREE_TYPE (decl);
tree cleanup;
my_friendly_assert (TREE_CODE (decl) == VAR_DECL my_friendly_assert (TREE_CODE (decl) == VAR_DECL
|| TREE_CODE (decl) == RESULT_DECL, || TREE_CODE (decl) == RESULT_DECL,
@ -7952,17 +7975,9 @@ initialize_local_var (tree decl, tree init)
} }
/* Generate a cleanup, if necessary. */ /* Generate a cleanup, if necessary. */
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) cleanup = cxx_maybe_build_cleanup (decl);
{ if (DECL_SIZE (decl) && cleanup)
tree cleanup; finish_decl_cleanup (decl, 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);
}
} }
/* Finish processing of a declaration; /* Finish processing of a declaration;
@ -7991,6 +8006,8 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
return; return;
} }
my_friendly_assert (TREE_CODE (decl) != RESULT_DECL, 20030619);
/* If a name was specified, get the string. */ /* If a name was specified, get the string. */
if (global_scope_p (current_binding_level)) if (global_scope_p (current_binding_level))
asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree); 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) if (processing_template_decl)
{ {
/* Add this declaration to the statement-tree. */ /* Add this declaration to the statement-tree. */
if (at_function_scope_p () if (at_function_scope_p ())
&& TREE_CODE (decl) != RESULT_DECL)
add_decl_stmt (decl); add_decl_stmt (decl);
if (init && DECL_INITIAL (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)); SET_DECL_ASSEMBLER_NAME (decl, get_identifier (asmspec));
make_decl_rtl (decl, 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) else if (TREE_CODE (decl) == VAR_DECL)
{ {
/* Only PODs can have thread-local storage. Other types may require /* 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 /* Add this declaration to the statement-tree. This needs to happen
after the call to check_initializer so that the DECL_STMT for a 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. */ reference temp is added before the DECL_STMT for the reference itself. */
if (building_stmt_tree () if (at_function_scope_p ())
&& at_function_scope_p ()
&& TREE_CODE (decl) != RESULT_DECL)
add_decl_stmt (decl); add_decl_stmt (decl);
if (TREE_CODE (decl) == VAR_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, /* Output the assembler code and/or RTL code for variables and functions,
unless the type is an undefined structure or union. unless the type is an undefined structure or union.
If not, it will get done when the type is completed. */ If not, it will get done when the type is completed. */
if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
|| TREE_CODE (decl) == RESULT_DECL)
{ {
if (TREE_CODE (decl) == VAR_DECL) if (TREE_CODE (decl) == VAR_DECL)
maybe_commonize_var (decl); maybe_commonize_var (decl);

View File

@ -37,12 +37,6 @@ extern tree grokdeclarator (tree, tree, enum decl_context, int, tree*);
or a chain or parameter decls here. */ or a chain or parameter decls here. */
extern GTY(()) tree last_function_parms; 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 #ifdef DEBUG_CP_BINDING_LEVELS
/* Purely for debugging purposes. */ /* Purely for debugging purposes. */
extern int debug_bindings_indentation; extern int debug_bindings_indentation;

View File

@ -1886,8 +1886,7 @@ get_guard (tree decl)
DECL_ARTIFICIAL (guard) = 1; DECL_ARTIFICIAL (guard) = 1;
TREE_USED (guard) = 1; TREE_USED (guard) = 1;
pushdecl_top_level (guard); pushdecl_top_level_and_finish (guard, NULL_TREE);
cp_finish_decl (guard, NULL_TREE, NULL_TREE, 0);
} }
return guard; return guard;
} }

View File

@ -364,9 +364,8 @@ get_tinfo_decl (tree type)
DECL_EXTERNAL (d) = 1; DECL_EXTERNAL (d) = 1;
SET_DECL_ASSEMBLER_NAME (d, name); SET_DECL_ASSEMBLER_NAME (d, name);
DECL_COMDAT (d) = 1; 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)) if (CLASS_TYPE_P (type))
CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type)) = d; 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, SET_DECL_ASSEMBLER_NAME (name_decl,
mangle_typeinfo_string_for_type (target)); mangle_typeinfo_string_for_type (target));
DECL_INITIAL (name_decl) = name_string; DECL_INITIAL (name_decl) = name_string;
cp_finish_decl (name_decl, name_string, NULL_TREE, 0); pushdecl_top_level_and_finish (name_decl, name_string);
pushdecl_top_level (name_decl);
} }
vtable_ptr = TINFO_VTABLE_DECL (desc); vtable_ptr = TINFO_VTABLE_DECL (desc);

View File

@ -1,3 +1,8 @@
2003-06-19 Mark Mitchell <mark@codesourcery.com>
PR c++/11041
* g++.dg/init/ref7.C: New test.
2003-06-19 Matt Austern <austern@apple.com> 2003-06-19 Matt Austern <austern@apple.com>
PR c++/11228 PR c++/11228

View File

@ -0,0 +1,9 @@
class hop
{
public:
hop operator* () const;
};
int main(void)
{
const hop &x = *x;
}