Commit eb448459 by Mike Stump

91th Cygnus<->FSF quick merge

From-SVN: r14007
parent ebcf525f
Thu May 1 18:26:37 1997 Mike Stump <mrs@cygnus.com>
* except.c (expand_exception_blocks): Ensure that we flow through
the end of the exception region for the exception specification.
Move exception region for the exception specification in, so that
it doesn't protect the parm cleanup. Remove some obsolete code.
* decl.c (store_parm_decls): Likewise.
(finish_function): Likewise.
Tue Apr 29 15:38:54 1997 Jason Merrill <jason@yorick.cygnus.com>
* init.c (build_new): Fix nothrow handling.
Tue Apr 29 14:29:50 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* init.c (emit_base_init): Don't warn about the initialization
list for an artificial member.
Fri Apr 25 17:47:59 1997 Brendan Kehoe <brendan@lisa.cygnus.com>
* expr.c (do_case): Handle !START case for the error msg.
Fri Apr 25 11:55:23 1997 Jason Merrill <jason@yorick.cygnus.com>
* decl2.c, lang-options.h: New option -Weffc++.
* class.c, decl.c, init.c, typeck.c: Move Effective C++ warnings
to -Weffc++.
* decl2.c (finish_prevtable_vardecl): Change NO_LINKAGE_HEURISTICS
to MULTIPLE_SYMBOL_SPACES.
Wed Apr 23 18:06:50 1997 Jason Merrill <jason@yorick.cygnus.com>
* method.c (emit_thunk, generic case): Set current_function_is_thunk.
* method.c (emit_thunk, macro case): Set up DECL_RESULT.
* typeck.c (c_expand_return): Don't complain about returning void
to void in an artificial function.
* method.c (make_thunk): Change settings of READONLY/VOLATILE,
don't set DECL_RESULT, set DECL_ARTIFICIAL.
(emit_thunk, generic code): Also set up DECL_LANG_SPECIFIC.
Wed Apr 23 14:43:06 1997 Mike Stump <mrs@cygnus.com> Wed Apr 23 14:43:06 1997 Mike Stump <mrs@cygnus.com>
* init.c (init_decl_processing): Add supoprt for setjmp/longjmp based * init.c (init_decl_processing): Add supoprt for setjmp/longjmp based
......
...@@ -3587,7 +3587,7 @@ finish_struct_1 (t, warn_anon) ...@@ -3587,7 +3587,7 @@ finish_struct_1 (t, warn_anon)
} }
/* Effective C++ rule 11. */ /* Effective C++ rule 11. */
if (has_pointers && extra_warnings if (has_pointers && warn_ecpp
&& ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t))) && ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
{ {
cp_warning ("`%#T' has pointer data members", t); cp_warning ("`%#T' has pointer data members", t);
......
...@@ -238,7 +238,12 @@ extern int warn_nonvdtor; ...@@ -238,7 +238,12 @@ extern int warn_nonvdtor;
extern int warn_pmf2ptr; extern int warn_pmf2ptr;
/* Nonzero means warn about violation of some Effective C++ style rules. */
extern int warn_ecpp;
/* Non-zero means warn when a function is declared extern and later inline. */ /* Non-zero means warn when a function is declared extern and later inline. */
extern int warn_extern_inline; extern int warn_extern_inline;
/* Nonzero means to treat bitfields as unsigned unless they say `signed'. */ /* Nonzero means to treat bitfields as unsigned unless they say `signed'. */
......
...@@ -10137,7 +10137,7 @@ grok_op_properties (decl, virtualp, friendp) ...@@ -10137,7 +10137,7 @@ grok_op_properties (decl, virtualp, friendp)
} }
/* More Effective C++ rule 6. */ /* More Effective C++ rule 6. */
if (extra_warnings if (warn_ecpp
&& (name == ansi_opname[(int) POSTINCREMENT_EXPR] && (name == ansi_opname[(int) POSTINCREMENT_EXPR]
|| name == ansi_opname[(int) POSTDECREMENT_EXPR])) || name == ansi_opname[(int) POSTDECREMENT_EXPR]))
{ {
...@@ -10182,7 +10182,7 @@ grok_op_properties (decl, virtualp, friendp) ...@@ -10182,7 +10182,7 @@ grok_op_properties (decl, virtualp, friendp)
} }
/* More Effective C++ rule 7. */ /* More Effective C++ rule 7. */
if (extra_warnings if (warn_ecpp
&& (name == ansi_opname [TRUTH_ANDIF_EXPR] && (name == ansi_opname [TRUTH_ANDIF_EXPR]
|| name == ansi_opname [TRUTH_ORIF_EXPR] || name == ansi_opname [TRUTH_ORIF_EXPR]
|| name == ansi_opname [COMPOUND_EXPR])) || name == ansi_opname [COMPOUND_EXPR]))
...@@ -10191,7 +10191,7 @@ grok_op_properties (decl, virtualp, friendp) ...@@ -10191,7 +10191,7 @@ grok_op_properties (decl, virtualp, friendp)
} }
/* Effective C++ rule 23. */ /* Effective C++ rule 23. */
if (extra_warnings if (warn_ecpp
&& list_length (argtypes) == 3 && list_length (argtypes) == 3
&& (name == ansi_opname [PLUS_EXPR] && (name == ansi_opname [PLUS_EXPR]
|| name == ansi_opname [MINUS_EXPR] || name == ansi_opname [MINUS_EXPR]
...@@ -10499,7 +10499,7 @@ xref_basetypes (code_type_node, name, ref, binfo) ...@@ -10499,7 +10499,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
/* Effective C++ rule 14. The case of virtual functions but /* Effective C++ rule 14. The case of virtual functions but
non-virtual dtor is handled in finish_struct_1. */ non-virtual dtor is handled in finish_struct_1. */
if (warn_nonvdtor && ! TYPE_VIRTUAL_P (basetype) if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype)
&& TYPE_HAS_DESTRUCTOR (basetype)) && TYPE_HAS_DESTRUCTOR (basetype))
cp_warning ("base class `%#T' has a non-virtual destructor", cp_warning ("base class `%#T' has a non-virtual destructor",
basetype); basetype);
...@@ -11030,7 +11030,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p) ...@@ -11030,7 +11030,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
warning ("return-type defaults to `int'"); warning ("return-type defaults to `int'");
/* Effective C++ rule 15. See also c_expand_return. */ /* Effective C++ rule 15. See also c_expand_return. */
if (extra_warnings if (warn_ecpp
&& DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR] && DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR]
&& TREE_TYPE (fntype) == void_type_node) && TREE_TYPE (fntype) == void_type_node)
cp_warning ("`operator=' should return a reference to `*this'"); cp_warning ("`operator=' should return a reference to `*this'");
...@@ -11379,10 +11379,22 @@ store_parm_decls () ...@@ -11379,10 +11379,22 @@ store_parm_decls ()
if (! processing_template_decl) if (! processing_template_decl)
expand_function_start (fndecl, parms_have_cleanups); expand_function_start (fndecl, parms_have_cleanups);
current_function_parms_stored = 1;
/* If this function is `main', emit a call to `__main'
to run global initializers, etc. */
if (DECL_NAME (fndecl)
&& IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0
&& DECL_CONTEXT (fndecl) == NULL_TREE)
{
expand_main_function ();
}
/* Now that we have initialized the parms, we can start their /* Now that we have initialized the parms, we can start their
cleanups. We cannot do this before, since expand_decl_cleanup cleanups. We cannot do this before, since expand_decl_cleanup
should not be called before the parm can be used. */ should not be called before the parm can be used. */
if (parms_have_cleanups if (cleanups
&& ! processing_template_decl) && ! processing_template_decl)
{ {
for (cleanups = nreverse (cleanups); cleanups; cleanups = TREE_CHAIN (cleanups)) for (cleanups = nreverse (cleanups); cleanups; cleanups = TREE_CHAIN (cleanups))
...@@ -11402,41 +11414,13 @@ store_parm_decls () ...@@ -11402,41 +11414,13 @@ store_parm_decls ()
expand_start_bindings (0); expand_start_bindings (0);
} }
current_function_parms_stored = 1;
/* If this function is `main', emit a call to `__main'
to run global initializers, etc. */
if (DECL_NAME (fndecl)
&& IDENTIFIER_LENGTH (DECL_NAME (fndecl)) == 4
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "main") == 0
&& DECL_CONTEXT (fndecl) == NULL_TREE)
{
expand_main_function ();
}
/* Take care of exception handling things. */
if (! processing_template_decl && flag_exceptions) if (! processing_template_decl && flag_exceptions)
{ {
rtx insns;
start_sequence ();
#if 0
/* Mark the start of a stack unwinder if we need one. */
start_eh_unwinder ();
#endif
#if 0
/* Do the starting of the exception specifications, if we have any. */ /* Do the starting of the exception specifications, if we have any. */
if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))) if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
expand_start_eh_spec (); expand_start_eh_spec ();
#endif
insns = get_insns ();
end_sequence ();
if (insns)
store_after_parms (insns);
} }
last_dtor_insn = get_last_insn (); last_dtor_insn = get_last_insn ();
} }
...@@ -11881,6 +11865,9 @@ finish_function (lineno, call_poplevel, nested) ...@@ -11881,6 +11865,9 @@ finish_function (lineno, call_poplevel, nested)
&& ! DECL_NAME (DECL_RESULT (current_function_decl))) && ! DECL_NAME (DECL_RESULT (current_function_decl)))
no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
if (flag_exceptions)
expand_exception_blocks ();
/* If this function is supposed to return a value, ensure that /* If this function is supposed to return a value, ensure that
we do not fall into the cleanups by mistake. The end of our we do not fall into the cleanups by mistake. The end of our
function will look like this: function will look like this:
...@@ -11913,11 +11900,10 @@ finish_function (lineno, call_poplevel, nested) ...@@ -11913,11 +11900,10 @@ finish_function (lineno, call_poplevel, nested)
to catch cleanup-generated temporaries. */ to catch cleanup-generated temporaries. */
expand_end_bindings (0, 0, 0); expand_end_bindings (0, 0, 0);
poplevel (0, 0, 0); poplevel (0, 0, 0);
}
if (cleanup_label) /* Emit label at beginning of cleanup code for parameters. */
/* Emit label at beginning of cleanup code for parameters. */ emit_label (cleanup_label);
emit_label (cleanup_label); }
/* Get return value into register if that's where it's supposed to be. */ /* Get return value into register if that's where it's supposed to be. */
if (original_result_rtx) if (original_result_rtx)
...@@ -11937,9 +11923,6 @@ finish_function (lineno, call_poplevel, nested) ...@@ -11937,9 +11923,6 @@ finish_function (lineno, call_poplevel, nested)
/* Generate rtl for function exit. */ /* Generate rtl for function exit. */
expand_function_end (input_filename, lineno, 1); expand_function_end (input_filename, lineno, 1);
if (flag_exceptions)
expand_exception_blocks ();
} }
/* This must come after expand_function_end because cleanups might /* This must come after expand_function_end because cleanups might
......
...@@ -244,6 +244,10 @@ int warn_synth; ...@@ -244,6 +244,10 @@ int warn_synth;
into a pointer to (void or function). */ into a pointer to (void or function). */
int warn_pmf2ptr = 1; int warn_pmf2ptr = 1;
/* Nonzero means warn about violation of some Effective C++ style rules. */
int warn_ecpp = 0;
/* Nonzero means `$' can be in an identifier. /* Nonzero means `$' can be in an identifier.
See cccp.c for reasons why this breaks some obscure ANSI C programs. */ See cccp.c for reasons why this breaks some obscure ANSI C programs. */
...@@ -579,6 +583,8 @@ lang_decode_option (p) ...@@ -579,6 +583,8 @@ lang_decode_option (p)
warn_synth = setting; warn_synth = setting;
else if (!strcmp (p, "pmf-conversions")) else if (!strcmp (p, "pmf-conversions"))
warn_pmf2ptr = setting; warn_pmf2ptr = setting;
else if (!strcmp (p, "effc++"))
warn_ecpp = setting;
else if (!strcmp (p, "comment")) else if (!strcmp (p, "comment"))
; /* cpp handles this one. */ ; /* cpp handles this one. */
else if (!strcmp (p, "comments")) else if (!strcmp (p, "comments"))
...@@ -2413,7 +2419,7 @@ finish_prevtable_vardecl (prev, vars) ...@@ -2413,7 +2419,7 @@ finish_prevtable_vardecl (prev, vars)
tree ctype = DECL_CONTEXT (vars); tree ctype = DECL_CONTEXT (vars);
import_export_template (ctype); import_export_template (ctype);
#ifndef NO_LINKAGE_HEURISTICS #ifndef MULTIPLE_SYMBOL_SPACES
if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype) if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype)
&& ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)) && ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
{ {
......
...@@ -917,13 +917,11 @@ void ...@@ -917,13 +917,11 @@ void
expand_exception_blocks () expand_exception_blocks ()
{ {
rtx funcend; rtx funcend;
rtx insn, insns; rtx insns;
rtx eh_spec_insns = NULL_RTX;
start_sequence (); start_sequence ();
funcend = gen_label_rtx (); funcend = gen_label_rtx ();
emit_jump (funcend);
start_sequence (); start_sequence ();
...@@ -935,32 +933,26 @@ expand_exception_blocks () ...@@ -935,32 +933,26 @@ expand_exception_blocks ()
insns = get_insns (); insns = get_insns ();
end_sequence (); end_sequence ();
/* Do this after we expand leftover cleanups, so that the expand_eh_region_end #if 1
that expand_end_eh_spec does will match the right expand_eh_region_start, /* Do this after we expand leftover cleanups, so that the
and make sure it comes out before the terminate protected region. */ expand_eh_region_end that expand_end_eh_spec does will match the
right expand_eh_region_start, and make sure it comes out before
the terminate protected region. */
if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))) if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
{ {
#if 1 expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)));
{ push_to_sequence (insns);
rtx insns;
/* New... */
start_sequence ();
expand_start_eh_spec ();
eh_spec_insns = get_insns ();
end_sequence ();
}
#endif
expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)));
push_to_sequence (insns);
/* Now expand any new ones. */ /* Now expand any new ones. */
expand_leftover_cleanups (); expand_leftover_cleanups ();
insns = get_insns (); insns = get_insns ();
end_sequence (); end_sequence ();
} }
#endif
emit_jump (funcend);
if (insns) if (insns)
{ {
...@@ -983,22 +975,6 @@ expand_exception_blocks () ...@@ -983,22 +975,6 @@ expand_exception_blocks ()
expand_leftover_cleanups (); expand_leftover_cleanups ();
} }
{
/* Mark the end of the stack unwinder. */
rtx unwind_insns;
start_sequence ();
#if 0
end_eh_unwinder ();
#endif
unwind_insns = get_insns ();
end_sequence ();
if (unwind_insns)
{
insns = unwind_insns;
emit_insns (insns);
}
}
emit_label (funcend); emit_label (funcend);
/* Only if we had previous insns do we want to emit the jump around /* Only if we had previous insns do we want to emit the jump around
...@@ -1007,22 +983,7 @@ expand_exception_blocks () ...@@ -1007,22 +983,7 @@ expand_exception_blocks ()
insns = get_insns (); insns = get_insns ();
end_sequence (); end_sequence ();
#if 1 emit_insns (insns);
if (eh_spec_insns)
emit_insns_after (eh_spec_insns, get_insns ());
#else
if (eh_spec_insns)
store_after_parms (eh_spec_insns);
#endif
insn = get_last_insn ();
while (GET_CODE (insn) == NOTE
|| (GET_CODE (insn) == INSN
&& (GET_CODE (PATTERN (insn)) == USE
|| GET_CODE (PATTERN (insn)) == CLOBBER)))
insn = PREV_INSN (insn);
emit_insns_after (insns, insn);
} }
tree tree
......
...@@ -444,6 +444,8 @@ do_case (start, end) ...@@ -444,6 +444,8 @@ do_case (start, end)
{ {
if (end) if (end)
error ("case label within scope of cleanup or variable array"); error ("case label within scope of cleanup or variable array");
else if (! start)
error ("`default' label within scope of cleanup or variable array");
else else
cp_error ("case label `%E' within scope of cleanup or variable array", start); cp_error ("case label `%E' within scope of cleanup or variable array", start);
} }
......
...@@ -647,7 +647,8 @@ emit_base_init (t, immediately) ...@@ -647,7 +647,8 @@ emit_base_init (t, immediately)
from_init_list = 0; from_init_list = 0;
/* Effective C++ rule 12. */ /* Effective C++ rule 12. */
if (extra_warnings && init == NULL_TREE if (warn_ecpp && init == NULL_TREE
&& !DECL_ARTIFICIAL (member)
&& TREE_CODE (TREE_TYPE (member)) != ARRAY_TYPE) && TREE_CODE (TREE_TYPE (member)) != ARRAY_TYPE)
cp_warning ("`%D' should be initialized in the member initialization list", member); cp_warning ("`%D' should be initialized in the member initialization list", member);
} }
...@@ -1895,7 +1896,6 @@ build_offset_ref (type, name) ...@@ -1895,7 +1896,6 @@ build_offset_ref (type, name)
tree access; tree access;
/* unique functions are handled easily. */ /* unique functions are handled easily. */
unique:
access = compute_access (basebinfo, t); access = compute_access (basebinfo, t);
if (access == access_protected_node) if (access == access_protected_node)
{ {
...@@ -2415,10 +2415,12 @@ build_new (placement, decl, init, use_global_new) ...@@ -2415,10 +2415,12 @@ build_new (placement, decl, init, use_global_new)
return error_mark_node; return error_mark_node;
} }
nothrow = (placement /* If the first placement arg is of type nothrow_t, it's allowed to
&& TREE_TYPE (placement) return 0 on allocation failure. */
&& IS_AGGR_TYPE (TREE_TYPE (placement)) nothrow = (placement && TREE_VALUE (placement)
&& (TYPE_IDENTIFIER (TREE_TYPE (placement)) && TREE_TYPE (TREE_VALUE (placement))
&& IS_AGGR_TYPE (TREE_TYPE (TREE_VALUE (placement)))
&& (TYPE_IDENTIFIER (TREE_TYPE (TREE_VALUE (placement)))
== get_identifier ("nothrow_t"))); == get_identifier ("nothrow_t")));
check_new = flag_check_new || nothrow; check_new = flag_check_new || nothrow;
...@@ -3152,11 +3154,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) ...@@ -3152,11 +3154,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
int flags; int flags;
int use_global_delete; int use_global_delete;
{ {
tree function;
tree member; tree member;
tree expr; tree expr;
tree ref; tree ref;
int ptr;
if (addr == error_mark_node) if (addr == error_mark_node)
return error_mark_node; return error_mark_node;
...@@ -3190,7 +3190,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) ...@@ -3190,7 +3190,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
/* throw away const and volatile on target type of addr */ /* throw away const and volatile on target type of addr */
addr = convert_force (build_pointer_type (type), addr, 0); addr = convert_force (build_pointer_type (type), addr, 0);
ref = build_indirect_ref (addr, NULL_PTR); ref = build_indirect_ref (addr, NULL_PTR);
ptr = 1;
} }
else if (TREE_CODE (type) == ARRAY_TYPE) else if (TREE_CODE (type) == ARRAY_TYPE)
{ {
...@@ -3221,7 +3220,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) ...@@ -3221,7 +3220,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
addr = convert_force (build_pointer_type (type), addr, 0); addr = convert_force (build_pointer_type (type), addr, 0);
ref = build_indirect_ref (addr, NULL_PTR); ref = build_indirect_ref (addr, NULL_PTR);
ptr = 0;
} }
my_friendly_assert (IS_AGGR_TYPE (type), 220); my_friendly_assert (IS_AGGR_TYPE (type), 220);
...@@ -3250,12 +3248,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete) ...@@ -3250,12 +3248,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
of the base classes; otherwise, we must do that here. */ of the base classes; otherwise, we must do that here. */
if (TYPE_HAS_DESTRUCTOR (type)) if (TYPE_HAS_DESTRUCTOR (type))
{ {
tree parms = build_tree_list (NULL_TREE, addr);
tree dtor = DECL_MAIN_VARIANT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1));
tree passed_auto_delete; tree passed_auto_delete;
tree do_delete = NULL_TREE; tree do_delete = NULL_TREE;
tree ifexp; tree ifexp;
int nonnull;
if (use_global_delete) if (use_global_delete)
{ {
......
...@@ -102,3 +102,5 @@ Boston, MA 02111-1307, USA. */ ...@@ -102,3 +102,5 @@ Boston, MA 02111-1307, USA. */
"-Wno-synth", "-Wno-synth",
"-Wpmf-conversions", "-Wpmf-conversions",
"-Wno-pmf-conversions", "-Wno-pmf-conversions",
"-Weffc++",
"-Wno-effc++",
...@@ -1698,30 +1698,29 @@ make_thunk (function, delta) ...@@ -1698,30 +1698,29 @@ make_thunk (function, delta)
} }
if (thunk == NULL_TREE) if (thunk == NULL_TREE)
{ {
thunk = build_lang_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl)); thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl));
DECL_RESULT (thunk) TREE_READONLY (thunk) = TREE_READONLY (func_decl);
= build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (vtable_entry_type))); TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (func_decl);
TREE_READONLY (thunk) = TYPE_READONLY (TREE_TYPE (vtable_entry_type));
TREE_THIS_VOLATILE (thunk) = TYPE_VOLATILE (TREE_TYPE (vtable_entry_type));
make_function_rtl (thunk);
comdat_linkage (thunk); comdat_linkage (thunk);
TREE_SET_CODE (thunk, THUNK_DECL); TREE_SET_CODE (thunk, THUNK_DECL);
DECL_INITIAL (thunk) = function; DECL_INITIAL (thunk) = function;
THUNK_DELTA (thunk) = delta; THUNK_DELTA (thunk) = delta;
DECL_EXTERNAL (thunk) = 1; DECL_EXTERNAL (thunk) = 1;
DECL_ARTIFICIAL (thunk) = 1;
/* So that finish_file can write out any thunks that need to be: */ /* So that finish_file can write out any thunks that need to be: */
pushdecl_top_level (thunk); pushdecl_top_level (thunk);
} }
return thunk; return thunk;
} }
/* Emit the definition of a C++ multiple inheritance vtable thunk. */
void void
emit_thunk (thunk_fndecl) emit_thunk (thunk_fndecl)
tree thunk_fndecl; tree thunk_fndecl;
{ {
tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0); tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0);
int delta = THUNK_DELTA (thunk_fndecl); int delta = THUNK_DELTA (thunk_fndecl);
char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
if (TREE_ASM_WRITTEN (thunk_fndecl)) if (TREE_ASM_WRITTEN (thunk_fndecl))
return; return;
...@@ -1736,21 +1735,31 @@ emit_thunk (thunk_fndecl) ...@@ -1736,21 +1735,31 @@ emit_thunk (thunk_fndecl)
TREE_SET_CODE (thunk_fndecl, FUNCTION_DECL); TREE_SET_CODE (thunk_fndecl, FUNCTION_DECL);
{
#ifdef ASM_OUTPUT_MI_THUNK #ifdef ASM_OUTPUT_MI_THUNK
current_function_decl = thunk_fndecl; char *fnname;
temporary_allocation (); current_function_decl = thunk_fndecl;
assemble_start_function (thunk_fndecl, fnname); temporary_allocation ();
ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function); DECL_RESULT (thunk_fndecl)
assemble_end_function (thunk_fndecl, fnname); = build_decl (RESULT_DECL, 0, integer_type_node);
permanent_allocation (1); make_function_rtl (thunk_fndecl);
current_function_decl = 0; fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
assemble_start_function (thunk_fndecl, fnname);
ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function);
assemble_end_function (thunk_fndecl, fnname);
permanent_allocation (1);
current_function_decl = 0;
#else /* ASM_OUTPUT_MI_THUNK */ #else /* ASM_OUTPUT_MI_THUNK */
if (varargs_function_p (function)) /* If we don't have the necessary macro for efficient thunks, generate a
cp_error ("generic thunk code does not work for variadic function `%#D'", thunk function that just makes a call to the real function.
function); Unfortunately, this doesn't work for varargs. */
{
tree a, t; tree a, t;
if (varargs_function_p (function))
cp_error ("generic thunk code fails for method `%#D' which uses `...'",
function);
/* Set up clone argument trees for the thunk. */ /* Set up clone argument trees for the thunk. */
t = NULL_TREE; t = NULL_TREE;
for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a)) for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a))
...@@ -1763,9 +1772,14 @@ emit_thunk (thunk_fndecl) ...@@ -1763,9 +1772,14 @@ emit_thunk (thunk_fndecl)
a = nreverse (t); a = nreverse (t);
DECL_ARGUMENTS (thunk_fndecl) = a; DECL_ARGUMENTS (thunk_fndecl) = a;
DECL_RESULT (thunk_fndecl) = NULL_TREE; DECL_RESULT (thunk_fndecl) = NULL_TREE;
DECL_LANG_SPECIFIC (thunk_fndecl) = DECL_LANG_SPECIFIC (function);
copy_lang_decl (thunk_fndecl);
DECL_INTERFACE_KNOWN (thunk_fndecl) = 1;
DECL_NOT_REALLY_EXTERN (thunk_fndecl) = 1;
start_function (NULL_TREE, thunk_fndecl, NULL_TREE, 1); start_function (NULL_TREE, thunk_fndecl, NULL_TREE, 1);
store_parm_decls (); store_parm_decls ();
current_function_is_thunk = 1;
/* Build up the call to the real function. */ /* Build up the call to the real function. */
t = build_int_2 (delta, -1 * (delta < 0)); t = build_int_2 (delta, -1 * (delta < 0));
...@@ -1779,8 +1793,8 @@ emit_thunk (thunk_fndecl) ...@@ -1779,8 +1793,8 @@ emit_thunk (thunk_fndecl)
c_expand_return (t); c_expand_return (t);
finish_function (lineno, 0, 0); finish_function (lineno, 0, 0);
}
#endif /* ASM_OUTPUT_MI_THUNK */ #endif /* ASM_OUTPUT_MI_THUNK */
}
TREE_SET_CODE (thunk_fndecl, THUNK_DECL); TREE_SET_CODE (thunk_fndecl, THUNK_DECL);
} }
......
...@@ -7105,7 +7105,7 @@ c_expand_return (retval) ...@@ -7105,7 +7105,7 @@ c_expand_return (retval)
} }
/* Effective C++ rule 15. See also start_function. */ /* Effective C++ rule 15. See also start_function. */
if (extra_warnings if (warn_ecpp
&& DECL_NAME (current_function_decl) == ansi_opname[(int) MODIFY_EXPR] && DECL_NAME (current_function_decl) == ansi_opname[(int) MODIFY_EXPR]
&& retval != current_class_ref) && retval != current_class_ref)
cp_warning ("`operator=' should return a reference to `*this'"); cp_warning ("`operator=' should return a reference to `*this'");
...@@ -7113,7 +7113,8 @@ c_expand_return (retval) ...@@ -7113,7 +7113,8 @@ c_expand_return (retval)
if (valtype == NULL_TREE || TREE_CODE (valtype) == VOID_TYPE) if (valtype == NULL_TREE || TREE_CODE (valtype) == VOID_TYPE)
{ {
current_function_returns_null = 1; current_function_returns_null = 1;
if (pedantic || TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) if ((pedantic && ! DECL_ARTIFICIAL (current_function_decl))
|| TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE)
pedwarn ("`return' with a value, in function returning void"); pedwarn ("`return' with a value, in function returning void");
expand_return (retval); expand_return (retval);
return; return;
......
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