Commit 170b020f by Mark Mitchell Committed by Mark Mitchell

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
parent 7a1d37e9
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
......
...@@ -6144,7 +6144,7 @@ initialize_reference (tree type, tree expr, tree decl) ...@@ -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) ...@@ -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. */
......
...@@ -3263,6 +3263,12 @@ extern GTY(()) varray_type local_classes; ...@@ -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); ...@@ -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);
......
...@@ -4143,18 +4143,40 @@ pushdecl_namespace_level (tree x) ...@@ -4143,18 +4143,40 @@ 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. */ /* 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 static tree
pushdecl_top_level (tree x) pushdecl_top_level_1 (tree x, tree *init)
{ {
timevar_push (TV_NAME_LOOKUP); timevar_push (TV_NAME_LOOKUP);
push_to_top_level (); push_to_top_level ();
x = pushdecl_namespace_level (x); x = pushdecl_namespace_level (x);
if (init)
cp_finish_decl (x, *init, NULL_TREE, 0);
pop_from_top_level (); pop_from_top_level ();
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); 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. */ /* Make the declaration of X appear in CLASS scope. */
void void
...@@ -7903,6 +7925,7 @@ static void ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -37,12 +37,6 @@ extern tree grokdeclarator (tree, tree, enum decl_context, int, tree*); ...@@ -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;
......
...@@ -1886,8 +1886,7 @@ get_guard (tree decl) ...@@ -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;
} }
......
...@@ -364,9 +364,8 @@ get_tinfo_decl (tree type) ...@@ -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) ...@@ -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);
......
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
......
class hop
{
public:
hop operator* () const;
};
int main(void)
{
const hop &x = *x;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment