diff options
author | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-05-02 01:42:58 +0000 |
---|---|---|
committer | mrs <mrs@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-05-02 01:42:58 +0000 |
commit | f85d646a3e067c12f99a5a79d5e17b0388ecd53f (patch) | |
tree | d15683fdd007eaa7a6e42cb25ad13d7a80886862 /gcc/cp | |
parent | a4e9e1fca80266d90b93e42c670a8922f7d9fd61 (diff) | |
download | gcc-f85d646a3e067c12f99a5a79d5e17b0388ecd53f.tar.gz |
91th Cygnus<->FSF quick merge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14007 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 43 | ||||
-rw-r--r-- | gcc/cp/class.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 5 | ||||
-rw-r--r-- | gcc/cp/decl.c | 67 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 8 | ||||
-rw-r--r-- | gcc/cp/except.c | 73 | ||||
-rw-r--r-- | gcc/cp/expr.c | 2 | ||||
-rw-r--r-- | gcc/cp/init.c | 21 | ||||
-rw-r--r-- | gcc/cp/lang-options.h | 2 | ||||
-rw-r--r-- | gcc/cp/method.c | 52 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 5 |
11 files changed, 146 insertions, 134 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2f9b6e2029e..d4231c18d2b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b527738f88d..8cddd980608 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ac00c5b573b..96dd1470a35 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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'. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 36dc140093a..749a2f35a42 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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); + /* 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 diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 1e8577af6b2..f7e20640694 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -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)) { diff --git a/gcc/cp/except.c b/gcc/cp/except.c index efe97626a74..45994ce1748 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -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 (); @@ -935,32 +933,26 @@ 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); + expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))); + push_to_sequence (insns); - /* Now expand any new ones. */ - expand_leftover_cleanups (); + /* Now expand any new ones. */ + expand_leftover_cleanups (); - insns = get_insns (); - end_sequence (); + 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 diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 118db30930d..9beee2823ff 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -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); } diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 332679d9857..662434eefa2 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -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) { diff --git a/gcc/cp/lang-options.h b/gcc/cp/lang-options.h index f2014c6a769..707282dae88 100644 --- a/gcc/cp/lang-options.h +++ b/gcc/cp/lang-options.h @@ -102,3 +102,5 @@ Boston, MA 02111-1307, USA. */ "-Wno-synth", "-Wpmf-conversions", "-Wno-pmf-conversions", + "-Weffc++", + "-Wno-effc++", diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 358e24a9469..cf26ab1db85 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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 - current_function_decl = thunk_fndecl; - temporary_allocation (); - 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; + 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); } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 97b6fbad834..4aee8a638aa 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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; |