summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2001-12-13 01:37:52 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2001-12-13 01:37:52 +0000
commitfb75f6dc972c9593017122a018fd3e96ed947b36 (patch)
tree4280f3d0abd19266afffae466528ebbb6dca66f8
parent7d6080d60a13e6133cfa079ec46ec2c21ffb11d2 (diff)
downloadgcc-fb75f6dc972c9593017122a018fd3e96ed947b36.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@47962 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog26
-rw-r--r--gcc/cp/call.c3
-rw-r--r--gcc/cp/class.c11
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/decl.c22
-rw-r--r--gcc/cp/method.c1
-rw-r--r--gcc/cp/semantics.c133
-rw-r--r--gcc/cp/typeck.c2
8 files changed, 67 insertions, 137 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 09e54531484..3a06bacf698 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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>
* cp-tree.h (DESTRUCTOR_DECL_PREFIX, DESTRUCTOR_NAME_P,
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 21049b8b3ef..8b1e2bb0814 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -4660,8 +4660,7 @@ build_new_method_call (instance, name, args, basetype_path, flags)
}
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;
if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE)
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 08ec1c9a33e..0b0d33f6031 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -5287,11 +5287,12 @@ fixed_type_or_null (instance, nonnull, cdtorp)
switch (TREE_CODE (instance))
{
case INDIRECT_REF:
- /* Check that we are not going through a cast of some sort. */
- if (TREE_TYPE (instance)
- == TREE_TYPE (TREE_TYPE (TREE_OPERAND (instance, 0))))
- instance = TREE_OPERAND (instance, 0);
- /* fall through... */
+ if (POINTER_TYPE_P (instance))
+ return NULL_TREE;
+ else
+ return fixed_type_or_null (TREE_OPERAND (instance, 0),
+ nonnull, cdtorp);
+
case CALL_EXPR:
/* This is a call to a constructor, hence it's never zero. */
if (TREE_HAS_CONSTRUCTOR (instance))
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index a0ceff08457..b68e0badb21 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -801,7 +801,6 @@ struct cp_language_function
{
struct language_function base;
- tree x_ctor_label;
tree x_dtor_label;
tree x_current_class_ptr;
tree x_current_class_ref;
@@ -836,11 +835,6 @@ struct cp_language_function
#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
PARM_DECL for the `this' pointer. The current_class_ref is an
expression for `*this'. */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 30050fe0dea..7e9692dbf8b 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8418,7 +8418,6 @@ start_cleanup_fn ()
pushdecl (fndecl);
start_function (/*specs=*/NULL_TREE, fndecl, NULL_TREE, SF_PRE_PARSED);
- do_pushlevel ();
interface_unknown = old_interface_unknown;
@@ -8432,8 +8431,6 @@ start_cleanup_fn ()
static void
end_cleanup_fn ()
{
- do_poplevel ();
-
expand_body (finish_function (0));
pop_from_top_level ();
@@ -13794,7 +13791,6 @@ store_parm_decls (current_function_parms)
{
register tree fndecl = current_function_decl;
register tree parm;
- int parms_have_cleanups = 0;
tree cleanups = NULL_TREE;
/* 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);
}
- /* 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. */
if (flag_exceptions && !processing_template_decl
&& flag_enforce_eh_specs
@@ -13935,16 +13926,6 @@ save_function_data (decl)
static void
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. */
add_stmt (build_stmt (CTOR_STMT));
}
@@ -14124,7 +14105,7 @@ finish_function (flags)
else if (DECL_MAIN_P (fndecl))
{
/* Make it so that `main' always returns 0 by default. */
-#ifdef VMS
+#ifdef VMS_TARGET
finish_return_stmt (integer_one_node);
#else
finish_return_stmt (integer_zero_node);
@@ -14575,7 +14556,6 @@ mark_lang_function (p)
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_current_class_ptr);
ggc_mark_tree (p->x_current_class_ref);
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 2424623a4b4..0cef1e3d5e1 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -462,6 +462,7 @@ use_thunk (thunk_fndecl, emit_p)
DECL_RESULT (thunk_fndecl) = NULL_TREE;
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. */
t = ssize_int (delta);
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index b0bb25b94f4..8dc792adb31 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -390,17 +390,7 @@ finish_return_stmt (expr)
expr = check_return_expr (expr);
if (!processing_template_decl)
{
- if (DECL_CONSTRUCTOR_P (current_function_decl) && ctor_label)
- {
- /* 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))
+ if (DECL_DESTRUCTOR_P (current_function_decl))
{
/* Similarly, all destructors must run destructors for
base-classes before returning. So, all returns in a
@@ -678,7 +668,7 @@ finish_cleanup (cleanup, try_block)
void
finish_function_try_block (try_block)
- tree try_block;
+ tree try_block;
{
if (TREE_CHAIN (try_block)
&& 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);
}
-/* Cache the value of this class's main virtual function table pointer
- in a register variable. This will save one indirection if a
- more than one virtual function call is made this function. */
+/* Do the initialization work necessary at the beginning of a constructor
+ or destructor. This means processing member initializers and setting
+ vtable pointers.
+
+ ??? The call to keep_next_level at the end applies to all functions, but
+ should probably go somewhere else. */
void
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);
- /* 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)
- 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)
- add_stmt (build_min_nt
- (CTOR_INITIALIZER,
- member_init_list, base_init_list));
- else
- {
- tree ctor_stmt;
+ tree ctor_stmt;
- /* Mark the beginning of the constructor. */
- ctor_stmt = build_stmt (CTOR_STMT);
- CTOR_BEGIN_P (ctor_stmt) = 1;
- add_stmt (ctor_stmt);
+ /* Mark the beginning of the constructor. */
+ ctor_stmt = build_stmt (CTOR_STMT);
+ CTOR_BEGIN_P (ctor_stmt) = 1;
+ add_stmt (ctor_stmt);
- /* And actually initialize the base-classes and members. */
- emit_base_init (member_init_list, base_init_list);
- }
+ /* And actually initialize the base-classes and members. */
+ emit_base_init (member_init_list, base_init_list);
}
- else if (DECL_DESTRUCTOR_P (current_function_decl)
- && !processing_template_decl)
+ else if (DECL_DESTRUCTOR_P (current_function_decl))
{
tree if_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
have a non-related vtable set up, we cannot avoid setting up
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 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. */
expand_start_bindings (2);
- /* Go through the PARM_DECLs for this function to see if any need
- 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);
+ expand_function_start (fn, /*parms_have_cleanups=*/0);
/* If this function is `main'. */
if (DECL_MAIN_P (fn))
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. */
if (current_function_return_value)
@@ -2647,7 +2626,6 @@ static void
genrtl_finish_function (fn)
tree fn;
{
- tree no_return_label = NULL_TREE;
tree t;
#if 0
@@ -2676,59 +2654,10 @@ genrtl_finish_function (fn)
/* Clean house because we will need to reorder insns here. */
do_pending_stack_adjust ();
- if (!dtor_label && !DECL_CONSTRUCTOR_P (fn)
- && return_label != NULL_RTX
- && ! DECL_NAME (DECL_RESULT (current_function_decl)))
- 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)
+ /* If we have a named return value, we need to force a return so that
+ the return register is USEd. */
+ if (DECL_NAME (DECL_RESULT (fn)))
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.
Expand_function_end will decrement this variable. So, we set the
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index c3d888c5a18..04a70304dbd 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6585,7 +6585,7 @@ check_return_expr (retval)
warning ("function declared `noreturn' has a `return' statement");
/* Check for various simple errors. */
- if (dtor_label)
+ if (DECL_DESTRUCTOR_P (current_function_decl))
{
if (retval)
error ("returning a value from a destructor");