decl.c (store_parm_decls): Remove parms_have_cleanups cruft.

* decl.c (store_parm_decls): Remove parms_have_cleanups cruft.
        * semantics.c (genrtl_start_function): Don't pass
        parms_have_cleanups or push an extra binding level.
        (genrtl_finish_function): Lose cleanup_label cruft.

        * cp-tree.h (struct cp_language_function): Remove x_ctor_label.
        (ctor_label): Remove.
        * semantics.c (finish_return_stmt): Lose ctor_label support.
        * decl.c (finish_constructor_body, mark_lang_function): Likewise.
        * typeck.c (check_return_expr): Check DECL_DESTRUCTOR_P, not
        dtor_label.

        * call.c (build_new_method_call): Let resolves_to_fixed_type_p
        check for [cd]tors.
        * class.c (fixed_type_or_null, case INDIRECT_REF): Fix.

        * decl.c (finish_function): Check VMS_TARGET, not VMS.

        * decl.c (start_cleanup_fn): Remove redundant pushlevel.
        (end_cleanup_fn): And poplevel.

        * semantics.c (setup_vtbl_ptr): Always build a CTOR_INITIALIZER
        if we're in a template.

From-SVN: r47962
This commit is contained in:
Jason Merrill 2001-12-12 20:37:52 -05:00 committed by Jason Merrill
parent aff8a8d52b
commit a0de9d2025
8 changed files with 67 additions and 137 deletions

View file

@ -1,3 +1,29 @@
2001-12-12 Jason Merrill <jason@redhat.com>
* decl.c (store_parm_decls): Remove parms_have_cleanups cruft.
* semantics.c (genrtl_start_function): Don't pass
parms_have_cleanups or push an extra binding level.
(genrtl_finish_function): Lose cleanup_label cruft.
* cp-tree.h (struct cp_language_function): Remove x_ctor_label.
(ctor_label): Remove.
* semantics.c (finish_return_stmt): Lose ctor_label support.
* decl.c (finish_constructor_body, mark_lang_function): Likewise.
* typeck.c (check_return_expr): Check DECL_DESTRUCTOR_P, not
dtor_label.
* call.c (build_new_method_call): Let resolves_to_fixed_type_p
check for [cd]tors.
* class.c (fixed_type_or_null, case INDIRECT_REF): Fix.
* decl.c (finish_function): Check VMS_TARGET, not VMS.
* decl.c (start_cleanup_fn): Remove redundant pushlevel.
(end_cleanup_fn): And poplevel.
* semantics.c (setup_vtbl_ptr): Always build a CTOR_INITIALIZER
if we're in a template.
2001-12-12 Jakub Jelinek <jakub@redhat.com> 2001-12-12 Jakub Jelinek <jakub@redhat.com>
* cp-tree.h (DESTRUCTOR_DECL_PREFIX, DESTRUCTOR_NAME_P, * cp-tree.h (DESTRUCTOR_DECL_PREFIX, DESTRUCTOR_NAME_P,

View file

@ -4660,8 +4660,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
} }
if (DECL_VINDEX (cand->fn) && ! (flags & LOOKUP_NONVIRTUAL) if (DECL_VINDEX (cand->fn) && ! (flags & LOOKUP_NONVIRTUAL)
&& ((instance == current_class_ref && (dtor_label || ctor_label)) && resolves_to_fixed_type_p (instance, 0))
|| resolves_to_fixed_type_p (instance, 0)))
flags |= LOOKUP_NONVIRTUAL; flags |= LOOKUP_NONVIRTUAL;
if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE) if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE)

View file

@ -5287,11 +5287,12 @@ fixed_type_or_null (instance, nonnull, cdtorp)
switch (TREE_CODE (instance)) switch (TREE_CODE (instance))
{ {
case INDIRECT_REF: case INDIRECT_REF:
/* Check that we are not going through a cast of some sort. */ if (POINTER_TYPE_P (instance))
if (TREE_TYPE (instance) return NULL_TREE;
== TREE_TYPE (TREE_TYPE (TREE_OPERAND (instance, 0)))) else
instance = TREE_OPERAND (instance, 0); return fixed_type_or_null (TREE_OPERAND (instance, 0),
/* fall through... */ nonnull, cdtorp);
case CALL_EXPR: case CALL_EXPR:
/* This is a call to a constructor, hence it's never zero. */ /* This is a call to a constructor, hence it's never zero. */
if (TREE_HAS_CONSTRUCTOR (instance)) if (TREE_HAS_CONSTRUCTOR (instance))

View file

@ -801,7 +801,6 @@ struct cp_language_function
{ {
struct language_function base; struct language_function base;
tree x_ctor_label;
tree x_dtor_label; tree x_dtor_label;
tree x_current_class_ptr; tree x_current_class_ptr;
tree x_current_class_ref; tree x_current_class_ref;
@ -836,11 +835,6 @@ struct cp_language_function
#define dtor_label cp_function_chain->x_dtor_label #define dtor_label cp_function_chain->x_dtor_label
/* In a constructor, the point at which we are ready to return
the pointer to the initialized object. */
#define ctor_label cp_function_chain->x_ctor_label
/* When we're processing a member function, current_class_ptr is the /* When we're processing a member function, current_class_ptr is the
PARM_DECL for the `this' pointer. The current_class_ref is an PARM_DECL for the `this' pointer. The current_class_ref is an
expression for `*this'. */ expression for `*this'. */

View file

@ -8418,7 +8418,6 @@ start_cleanup_fn ()
pushdecl (fndecl); pushdecl (fndecl);
start_function (/*specs=*/NULL_TREE, fndecl, NULL_TREE, SF_PRE_PARSED); start_function (/*specs=*/NULL_TREE, fndecl, NULL_TREE, SF_PRE_PARSED);
do_pushlevel ();
interface_unknown = old_interface_unknown; interface_unknown = old_interface_unknown;
@ -8432,8 +8431,6 @@ start_cleanup_fn ()
static void static void
end_cleanup_fn () end_cleanup_fn ()
{ {
do_poplevel ();
expand_body (finish_function (0)); expand_body (finish_function (0));
pop_from_top_level (); pop_from_top_level ();
@ -13794,7 +13791,6 @@ store_parm_decls (current_function_parms)
{ {
register tree fndecl = current_function_decl; register tree fndecl = current_function_decl;
register tree parm; register tree parm;
int parms_have_cleanups = 0;
tree cleanups = NULL_TREE; tree cleanups = NULL_TREE;
/* This is a chain of any other decls that came in among the parm /* This is a chain of any other decls that came in among the parm
@ -13875,11 +13871,6 @@ store_parm_decls (current_function_parms)
cleanups = TREE_CHAIN (cleanups); cleanups = TREE_CHAIN (cleanups);
} }
/* Create a binding contour which can be used to catch
cleanup-generated temporaries. */
if (parms_have_cleanups)
pushlevel (0);
/* Do the starting of the exception specifications, if we have any. */ /* Do the starting of the exception specifications, if we have any. */
if (flag_exceptions && !processing_template_decl if (flag_exceptions && !processing_template_decl
&& flag_enforce_eh_specs && flag_enforce_eh_specs
@ -13935,16 +13926,6 @@ save_function_data (decl)
static void static void
finish_constructor_body () finish_constructor_body ()
{ {
/* Any return from a constructor will end up here. */
if (ctor_label)
add_stmt (build_stmt (LABEL_STMT, ctor_label));
/* Clear CTOR_LABEL so that finish_return_stmt knows to really
generate the return, rather than a goto to CTOR_LABEL. */
ctor_label = NULL_TREE;
/* In check_return_expr we translate an empty return from a
constructor to a return of `this'. */
finish_return_stmt (NULL_TREE);
/* Mark the end of the constructor. */ /* Mark the end of the constructor. */
add_stmt (build_stmt (CTOR_STMT)); add_stmt (build_stmt (CTOR_STMT));
} }
@ -14124,7 +14105,7 @@ finish_function (flags)
else if (DECL_MAIN_P (fndecl)) else if (DECL_MAIN_P (fndecl))
{ {
/* Make it so that `main' always returns 0 by default. */ /* Make it so that `main' always returns 0 by default. */
#ifdef VMS #ifdef VMS_TARGET
finish_return_stmt (integer_one_node); finish_return_stmt (integer_one_node);
#else #else
finish_return_stmt (integer_zero_node); finish_return_stmt (integer_zero_node);
@ -14575,7 +14556,6 @@ mark_lang_function (p)
mark_c_language_function (&p->base); mark_c_language_function (&p->base);
ggc_mark_tree (p->x_ctor_label);
ggc_mark_tree (p->x_dtor_label); ggc_mark_tree (p->x_dtor_label);
ggc_mark_tree (p->x_current_class_ptr); ggc_mark_tree (p->x_current_class_ptr);
ggc_mark_tree (p->x_current_class_ref); ggc_mark_tree (p->x_current_class_ref);

View file

@ -462,6 +462,7 @@ use_thunk (thunk_fndecl, emit_p)
DECL_RESULT (thunk_fndecl) = NULL_TREE; DECL_RESULT (thunk_fndecl) = NULL_TREE;
start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED); start_function (NULL_TREE, thunk_fndecl, NULL_TREE, SF_PRE_PARSED);
/* We don't bother with a body block for thunks. */
/* Adjust the this pointer by the constant. */ /* Adjust the this pointer by the constant. */
t = ssize_int (delta); t = ssize_int (delta);

View file

@ -390,17 +390,7 @@ finish_return_stmt (expr)
expr = check_return_expr (expr); expr = check_return_expr (expr);
if (!processing_template_decl) if (!processing_template_decl)
{ {
if (DECL_CONSTRUCTOR_P (current_function_decl) && ctor_label) if (DECL_DESTRUCTOR_P (current_function_decl))
{
/* Even returns without a value in a constructor must return
`this'. We accomplish this by sending all returns in a
constructor to the CTOR_LABEL; finish_function emits code to
return a value there. When we finally generate the real
return statement, CTOR_LABEL is no longer set, and we fall
through into the normal return-processing code below. */
return finish_goto_stmt (ctor_label);
}
else if (DECL_DESTRUCTOR_P (current_function_decl))
{ {
/* Similarly, all destructors must run destructors for /* Similarly, all destructors must run destructors for
base-classes before returning. So, all returns in a base-classes before returning. So, all returns in a
@ -678,7 +668,7 @@ finish_cleanup (cleanup, try_block)
void void
finish_function_try_block (try_block) finish_function_try_block (try_block)
tree try_block; tree try_block;
{ {
if (TREE_CHAIN (try_block) if (TREE_CHAIN (try_block)
&& TREE_CODE (TREE_CHAIN (try_block)) == CTOR_INITIALIZER) && TREE_CODE (TREE_CHAIN (try_block)) == CTOR_INITIALIZER)
@ -1155,9 +1145,12 @@ finish_mem_initializers (init_list)
setup_vtbl_ptr (member_init_list, base_init_list); setup_vtbl_ptr (member_init_list, base_init_list);
} }
/* Cache the value of this class's main virtual function table pointer /* Do the initialization work necessary at the beginning of a constructor
in a register variable. This will save one indirection if a or destructor. This means processing member initializers and setting
more than one virtual function call is made this function. */ vtable pointers.
??? The call to keep_next_level at the end applies to all functions, but
should probably go somewhere else. */
void void
setup_vtbl_ptr (member_init_list, base_init_list) setup_vtbl_ptr (member_init_list, base_init_list)
@ -1166,31 +1159,26 @@ setup_vtbl_ptr (member_init_list, base_init_list)
{ {
my_friendly_assert (doing_semantic_analysis_p (), 19990919); my_friendly_assert (doing_semantic_analysis_p (), 19990919);
/* If we've already done this, there's no need to do it again. */ /* If we've already done this, break. */
if (vtbls_set_up_p) if (vtbls_set_up_p)
return; abort ();
if (DECL_CONSTRUCTOR_P (current_function_decl)) if (processing_template_decl)
add_stmt (build_min_nt (CTOR_INITIALIZER,
member_init_list, base_init_list));
else if (DECL_CONSTRUCTOR_P (current_function_decl))
{ {
if (processing_template_decl) tree ctor_stmt;
add_stmt (build_min_nt
(CTOR_INITIALIZER,
member_init_list, base_init_list));
else
{
tree ctor_stmt;
/* Mark the beginning of the constructor. */ /* Mark the beginning of the constructor. */
ctor_stmt = build_stmt (CTOR_STMT); ctor_stmt = build_stmt (CTOR_STMT);
CTOR_BEGIN_P (ctor_stmt) = 1; CTOR_BEGIN_P (ctor_stmt) = 1;
add_stmt (ctor_stmt); add_stmt (ctor_stmt);
/* And actually initialize the base-classes and members. */ /* And actually initialize the base-classes and members. */
emit_base_init (member_init_list, base_init_list); emit_base_init (member_init_list, base_init_list);
}
} }
else if (DECL_DESTRUCTOR_P (current_function_decl) else if (DECL_DESTRUCTOR_P (current_function_decl))
&& !processing_template_decl)
{ {
tree if_stmt; tree if_stmt;
tree compound_stmt; tree compound_stmt;
@ -1203,7 +1191,11 @@ setup_vtbl_ptr (member_init_list, base_init_list)
virtual dispatch to an overridden function that would need to virtual dispatch to an overridden function that would need to
have a non-related vtable set up, we cannot avoid setting up have a non-related vtable set up, we cannot avoid setting up
vtables in that case. We could change this to see if there vtables in that case. We could change this to see if there
is just one vtable. */ is just one vtable.
??? In the destructor for a class, the vtables are set
appropriately for that class. There will be no non-related
vtables. jason 2001-12-11. */
if_stmt = begin_if_stmt (); if_stmt = begin_if_stmt ();
/* If it is not safe to avoid setting up the vtables, then /* If it is not safe to avoid setting up the vtables, then
@ -2618,23 +2610,10 @@ genrtl_start_function (fn)
/* Create a binding level for the parameters. */ /* Create a binding level for the parameters. */
expand_start_bindings (2); expand_start_bindings (2);
/* Go through the PARM_DECLs for this function to see if any need expand_function_start (fn, /*parms_have_cleanups=*/0);
cleanups. */
for (parm = DECL_ARGUMENTS (fn); parm; parm = TREE_CHAIN (parm))
if (TREE_TYPE (parm) != error_mark_node
&& TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (parm)))
{
expand_function_start (fn, /*parms_have_cleanups=*/1);
break;
}
if (!parm)
expand_function_start (fn, /*parms_have_cleanups=*/0);
/* If this function is `main'. */ /* If this function is `main'. */
if (DECL_MAIN_P (fn)) if (DECL_MAIN_P (fn))
expand_main_function (); expand_main_function ();
/* Create a binding contour which can be used to catch
cleanup-generated temporaries. */
expand_start_bindings (2);
/* Give our named return value the same RTL as our RESULT_DECL. */ /* Give our named return value the same RTL as our RESULT_DECL. */
if (current_function_return_value) if (current_function_return_value)
@ -2647,7 +2626,6 @@ static void
genrtl_finish_function (fn) genrtl_finish_function (fn)
tree fn; tree fn;
{ {
tree no_return_label = NULL_TREE;
tree t; tree t;
#if 0 #if 0
@ -2676,59 +2654,10 @@ genrtl_finish_function (fn)
/* Clean house because we will need to reorder insns here. */ /* Clean house because we will need to reorder insns here. */
do_pending_stack_adjust (); do_pending_stack_adjust ();
if (!dtor_label && !DECL_CONSTRUCTOR_P (fn) /* If we have a named return value, we need to force a return so that
&& return_label != NULL_RTX the return register is USEd. */
&& ! DECL_NAME (DECL_RESULT (current_function_decl))) if (DECL_NAME (DECL_RESULT (fn)))
no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
/* If this function is supposed to return a value, ensure that
we do not fall into the cleanups by mistake. The end of our
function will look like this:
user code (may have return stmt somewhere)
goto no_return_label
cleanup_label:
cleanups
goto return_label
no_return_label:
NOTE_INSN_FUNCTION_END
return_label:
things for return
If the user omits a return stmt in the USER CODE section, we
will have a control path which reaches NOTE_INSN_FUNCTION_END.
Otherwise, we won't. */
if (no_return_label)
{
DECL_CONTEXT (no_return_label) = fn;
DECL_INITIAL (no_return_label) = error_mark_node;
DECL_SOURCE_FILE (no_return_label) = input_filename;
DECL_SOURCE_LINE (no_return_label) = lineno;
expand_goto (no_return_label);
}
if (cleanup_label)
{
/* Remove the binding contour which is used to catch
cleanup-generated temporaries. */
expand_end_bindings (0, 0, 0);
poplevel (0, 0, 0);
/* Emit label at beginning of cleanup code for parameters. */
emit_label (cleanup_label);
}
/* Finish building code that will trigger warnings if users forget
to make their functions return values. */
if (return_label)
emit_jump (return_label); emit_jump (return_label);
if (no_return_label)
{
/* We don't need to call `expand_*_return' here because we don't
need any cleanups here--this path of code is only for error
checking purposes. */
expand_label (no_return_label);
}
/* We hard-wired immediate_size_expand to zero in start_function. /* We hard-wired immediate_size_expand to zero in start_function.
Expand_function_end will decrement this variable. So, we set the Expand_function_end will decrement this variable. So, we set the

View file

@ -6585,7 +6585,7 @@ check_return_expr (retval)
warning ("function declared `noreturn' has a `return' statement"); warning ("function declared `noreturn' has a `return' statement");
/* Check for various simple errors. */ /* Check for various simple errors. */
if (dtor_label) if (DECL_DESTRUCTOR_P (current_function_decl))
{ {
if (retval) if (retval)
error ("returning a value from a destructor"); error ("returning a value from a destructor");