91th Cygnus<->FSF quick merge

From-SVN: r14007
This commit is contained in:
Mike Stump 1997-05-02 01:42:58 +00:00
parent ebcf525f58
commit eb4484594f
11 changed files with 148 additions and 136 deletions

View File

@ -1,3 +1,46 @@
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>
* init.c (init_decl_processing): Add supoprt for setjmp/longjmp based

View File

@ -3587,7 +3587,7 @@ finish_struct_1 (t, warn_anon)
}
/* Effective C++ rule 11. */
if (has_pointers && extra_warnings
if (has_pointers && warn_ecpp
&& ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))
{
cp_warning ("`%#T' has pointer data members", t);

View File

@ -238,7 +238,12 @@ extern int warn_nonvdtor;
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. */
extern int warn_extern_inline;
/* Nonzero means to treat bitfields as unsigned unless they say `signed'. */

View File

@ -10137,7 +10137,7 @@ grok_op_properties (decl, virtualp, friendp)
}
/* More Effective C++ rule 6. */
if (extra_warnings
if (warn_ecpp
&& (name == ansi_opname[(int) POSTINCREMENT_EXPR]
|| name == ansi_opname[(int) POSTDECREMENT_EXPR]))
{
@ -10182,7 +10182,7 @@ grok_op_properties (decl, virtualp, friendp)
}
/* More Effective C++ rule 7. */
if (extra_warnings
if (warn_ecpp
&& (name == ansi_opname [TRUTH_ANDIF_EXPR]
|| name == ansi_opname [TRUTH_ORIF_EXPR]
|| name == ansi_opname [COMPOUND_EXPR]))
@ -10191,7 +10191,7 @@ grok_op_properties (decl, virtualp, friendp)
}
/* Effective C++ rule 23. */
if (extra_warnings
if (warn_ecpp
&& list_length (argtypes) == 3
&& (name == ansi_opname [PLUS_EXPR]
|| name == ansi_opname [MINUS_EXPR]
@ -10499,7 +10499,7 @@ xref_basetypes (code_type_node, name, ref, binfo)
/* Effective C++ rule 14. The case of virtual functions but
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))
cp_warning ("base class `%#T' has a non-virtual destructor",
basetype);
@ -11030,7 +11030,7 @@ start_function (declspecs, declarator, attrs, pre_parsed_p)
warning ("return-type defaults to `int'");
/* Effective C++ rule 15. See also c_expand_return. */
if (extra_warnings
if (warn_ecpp
&& DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR]
&& TREE_TYPE (fntype) == void_type_node)
cp_warning ("`operator=' should return a reference to `*this'");
@ -11379,10 +11379,22 @@ store_parm_decls ()
if (! processing_template_decl)
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
cleanups. We cannot do this before, since expand_decl_cleanup
should not be called before the parm can be used. */
if (parms_have_cleanups
if (cleanups
&& ! processing_template_decl)
{
for (cleanups = nreverse (cleanups); cleanups; cleanups = TREE_CHAIN (cleanups))
@ -11402,41 +11414,13 @@ store_parm_decls ()
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)
{
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. */
if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
expand_start_eh_spec ();
#endif
insns = get_insns ();
end_sequence ();
if (insns)
store_after_parms (insns);
}
last_dtor_insn = get_last_insn ();
}
@ -11881,6 +11865,9 @@ finish_function (lineno, call_poplevel, nested)
&& ! DECL_NAME (DECL_RESULT (current_function_decl)))
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
we do not fall into the cleanups by mistake. The end of our
function will look like this:
@ -11913,11 +11900,10 @@ finish_function (lineno, call_poplevel, nested)
to catch cleanup-generated temporaries. */
expand_end_bindings (0, 0, 0);
poplevel (0, 0, 0);
}
if (cleanup_label)
/* Emit label at beginning of cleanup code for parameters. */
emit_label (cleanup_label);
}
/* Get return value into register if that's where it's supposed to be. */
if (original_result_rtx)
@ -11937,9 +11923,6 @@ finish_function (lineno, call_poplevel, nested)
/* Generate rtl for function exit. */
expand_function_end (input_filename, lineno, 1);
if (flag_exceptions)
expand_exception_blocks ();
}
/* This must come after expand_function_end because cleanups might

View File

@ -244,6 +244,10 @@ int warn_synth;
into a pointer to (void or function). */
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.
See cccp.c for reasons why this breaks some obscure ANSI C programs. */
@ -579,6 +583,8 @@ lang_decode_option (p)
warn_synth = setting;
else if (!strcmp (p, "pmf-conversions"))
warn_pmf2ptr = setting;
else if (!strcmp (p, "effc++"))
warn_ecpp = setting;
else if (!strcmp (p, "comment"))
; /* cpp handles this one. */
else if (!strcmp (p, "comments"))
@ -2413,7 +2419,7 @@ finish_prevtable_vardecl (prev, vars)
tree ctype = DECL_CONTEXT (vars);
import_export_template (ctype);
#ifndef NO_LINKAGE_HEURISTICS
#ifndef MULTIPLE_SYMBOL_SPACES
if (CLASSTYPE_INTERFACE_UNKNOWN (ctype) && TYPE_VIRTUAL_P (ctype)
&& ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
{

View File

@ -917,13 +917,11 @@ void
expand_exception_blocks ()
{
rtx funcend;
rtx insn, insns;
rtx eh_spec_insns = NULL_RTX;
rtx insns;
start_sequence ();
funcend = gen_label_rtx ();
emit_jump (funcend);
start_sequence ();
@ -936,22 +934,13 @@ expand_exception_blocks ()
insns = get_insns ();
end_sequence ();
/* Do this after we expand leftover cleanups, so that the 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 1
/* Do this after we expand leftover cleanups, so that the
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 1
{
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);
@ -961,6 +950,9 @@ expand_exception_blocks ()
insns = get_insns ();
end_sequence ();
}
#endif
emit_jump (funcend);
if (insns)
{
@ -983,22 +975,6 @@ expand_exception_blocks ()
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);
/* Only if we had previous insns do we want to emit the jump around
@ -1007,22 +983,7 @@ expand_exception_blocks ()
insns = get_insns ();
end_sequence ();
#if 1
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);
emit_insns (insns);
}
tree

View File

@ -444,6 +444,8 @@ do_case (start, end)
{
if (end)
error ("case label within scope of cleanup or variable array");
else if (! start)
error ("`default' label within scope of cleanup or variable array");
else
cp_error ("case label `%E' within scope of cleanup or variable array", start);
}

View File

@ -647,7 +647,8 @@ emit_base_init (t, immediately)
from_init_list = 0;
/* 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)
cp_warning ("`%D' should be initialized in the member initialization list", member);
}
@ -1895,7 +1896,6 @@ build_offset_ref (type, name)
tree access;
/* unique functions are handled easily. */
unique:
access = compute_access (basebinfo, t);
if (access == access_protected_node)
{
@ -2415,10 +2415,12 @@ build_new (placement, decl, init, use_global_new)
return error_mark_node;
}
nothrow = (placement
&& TREE_TYPE (placement)
&& IS_AGGR_TYPE (TREE_TYPE (placement))
&& (TYPE_IDENTIFIER (TREE_TYPE (placement))
/* If the first placement arg is of type nothrow_t, it's allowed to
return 0 on allocation failure. */
nothrow = (placement && TREE_VALUE (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")));
check_new = flag_check_new || nothrow;
@ -3152,11 +3154,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
int flags;
int use_global_delete;
{
tree function;
tree member;
tree expr;
tree ref;
int ptr;
if (addr == error_mark_node)
return error_mark_node;
@ -3190,7 +3190,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
/* throw away const and volatile on target type of addr */
addr = convert_force (build_pointer_type (type), addr, 0);
ref = build_indirect_ref (addr, NULL_PTR);
ptr = 1;
}
else if (TREE_CODE (type) == ARRAY_TYPE)
{
@ -3221,7 +3220,6 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
addr = convert_force (build_pointer_type (type), addr, 0);
ref = build_indirect_ref (addr, NULL_PTR);
ptr = 0;
}
my_friendly_assert (IS_AGGR_TYPE (type), 220);
@ -3250,12 +3248,9 @@ build_delete (type, addr, auto_delete, flags, use_global_delete)
of the base classes; otherwise, we must do that here. */
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 do_delete = NULL_TREE;
tree ifexp;
int nonnull;
if (use_global_delete)
{

View File

@ -102,3 +102,5 @@ Boston, MA 02111-1307, USA. */
"-Wno-synth",
"-Wpmf-conversions",
"-Wno-pmf-conversions",
"-Weffc++",
"-Wno-effc++",

View File

@ -1698,30 +1698,29 @@ make_thunk (function, delta)
}
if (thunk == NULL_TREE)
{
thunk = build_lang_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl));
DECL_RESULT (thunk)
= build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (vtable_entry_type)));
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);
thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl));
TREE_READONLY (thunk) = TREE_READONLY (func_decl);
TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (func_decl);
comdat_linkage (thunk);
TREE_SET_CODE (thunk, THUNK_DECL);
DECL_INITIAL (thunk) = function;
THUNK_DELTA (thunk) = delta;
DECL_EXTERNAL (thunk) = 1;
DECL_ARTIFICIAL (thunk) = 1;
/* So that finish_file can write out any thunks that need to be: */
pushdecl_top_level (thunk);
}
return thunk;
}
/* Emit the definition of a C++ multiple inheritance vtable thunk. */
void
emit_thunk (thunk_fndecl)
tree thunk_fndecl;
{
tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0);
int delta = THUNK_DELTA (thunk_fndecl);
char *fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0);
if (TREE_ASM_WRITTEN (thunk_fndecl))
return;
@ -1736,21 +1735,31 @@ emit_thunk (thunk_fndecl)
TREE_SET_CODE (thunk_fndecl, FUNCTION_DECL);
{
#ifdef ASM_OUTPUT_MI_THUNK
char *fnname;
current_function_decl = thunk_fndecl;
temporary_allocation ();
DECL_RESULT (thunk_fndecl)
= build_decl (RESULT_DECL, 0, integer_type_node);
make_function_rtl (thunk_fndecl);
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 */
if (varargs_function_p (function))
cp_error ("generic thunk code does not work for variadic function `%#D'",
function);
{
/* If we don't have the necessary macro for efficient thunks, generate a
thunk function that just makes a call to the real function.
Unfortunately, this doesn't work for varargs. */
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. */
t = NULL_TREE;
for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a))
@ -1763,9 +1772,14 @@ emit_thunk (thunk_fndecl)
a = nreverse (t);
DECL_ARGUMENTS (thunk_fndecl) = a;
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);
store_parm_decls ();
current_function_is_thunk = 1;
/* Build up the call to the real function. */
t = build_int_2 (delta, -1 * (delta < 0));
@ -1779,8 +1793,8 @@ emit_thunk (thunk_fndecl)
c_expand_return (t);
finish_function (lineno, 0, 0);
}
#endif /* ASM_OUTPUT_MI_THUNK */
}
TREE_SET_CODE (thunk_fndecl, THUNK_DECL);
}

View File

@ -7105,7 +7105,7 @@ c_expand_return (retval)
}
/* Effective C++ rule 15. See also start_function. */
if (extra_warnings
if (warn_ecpp
&& DECL_NAME (current_function_decl) == ansi_opname[(int) MODIFY_EXPR]
&& retval != current_class_ref)
cp_warning ("`operator=' should return a reference to `*this'");
@ -7113,7 +7113,8 @@ c_expand_return (retval)
if (valtype == NULL_TREE || TREE_CODE (valtype) == VOID_TYPE)
{
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");
expand_return (retval);
return;