diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-09-14 05:17:41 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-09-14 05:17:41 +0000 |
commit | 4f61e50d1cb81f3caced1e4cfe6ae22327a93925 (patch) | |
tree | f88d3a397949e313a970b9ac73ff0020ab38fcda | |
parent | f213a307a1e54b1a4a61904f697c605085fd4c84 (diff) | |
download | gcc-4f61e50d1cb81f3caced1e4cfe6ae22327a93925.tar.gz |
2009-09-14 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 151679
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@151680 138bc75d-0d04-0410-961f-82ee72b054a4
127 files changed, 2009 insertions, 856 deletions
diff --git a/ChangeLog b/ChangeLog index 6b53c3de876..c6e4293cc03 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-09-12 Joern Rennecke <joern.rennecke@embecosm.com> + + * MAINTAINERS (Write After Approval): Update my e-mail address, + and move from from here... + (Waiting for paperwork): To here. + 2009-09-09 Joseph Myers <joseph@codesourcery.com> * MAINTAINERS (Reviewers): Add self as driver reviewer. diff --git a/ChangeLog.MELT b/ChangeLog.MELT index c6c5ed3128d..fa65f4f78f3 100644 --- a/ChangeLog.MELT +++ b/ChangeLog.MELT @@ -1,4 +1,7 @@ +2009-09-14 Basile Starynkevitch <basile@starynkevitch.net> + MELT branch merged with trunk rev 151679 + 2009-09-10 Basile Starynkevitch <basile@starynkevitch.net> MELT branch merged with trunk rev 151586 diff --git a/MAINTAINERS b/MAINTAINERS index c1ac2488353..d1c5886b657 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -427,7 +427,6 @@ Dwarakanath Rajagopal dwarak.rajagopal@amd.com Ramana Radhakrishnan ramana.r@gmail.com Rolf Rasmussen rolfwr@gcc.gnu.org Volker Reichelt v.reichelt@netcologne.de -Joern Rennecke joern.rennecke@arc.com Bernhard Reutner-Fischer rep.dot.nop@gmail.com Tom Rix trix@redhat.com Craig Rodrigues rodrigc@gcc.gnu.org @@ -480,6 +479,10 @@ Jon Ziegler jonz@apple.com Roman Zippel zippel@linux-m68k.org Josef Zlomek josef.zlomek@email.cz +Waiting for paperwork: + +Joern Rennecke joern.rennecke@embecosm.com + Bug database only accounts James Dennett jdennett@acm.org diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog index f5d7e2e5fc1..9f05a757d69 100644 --- a/boehm-gc/ChangeLog +++ b/boehm-gc/ChangeLog @@ -1,3 +1,10 @@ +2009-09-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.am (libgcjgc_la_LINK, gctest_LINK): New. + (gctest_LDADD): Depend on libgcjgc.la instead of ./libgcjgc.la, + so that library dependency resolution works with portable make. + * Makefile.in: Regenerate. + 2009-09-08 Alexandre Oliva <aoliva@redhat.com> * configure: Rebuilt with modified libtool.m4. diff --git a/boehm-gc/Makefile.am b/boehm-gc/Makefile.am index 843891110c0..b074ac6df48 100644 --- a/boehm-gc/Makefile.am +++ b/boehm-gc/Makefile.am @@ -40,6 +40,7 @@ extra_ldflags_libgc = @extra_ldflags_libgc@ libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS) $(UNWINDLIBS) libgcjgc_la_DEPENDENCIES = @addobjs@ libgcjgc_la_LDFLAGS = $(extra_ldflags_libgc) -version-info 1:2:0 -rpath $(toolexeclibdir) +libgcjgc_la_LINK = $(LINK) $(libgcjgc_la_LDFLAGS) libgcjgc_convenience_la_LIBADD = @addobjs@ libgcjgc_convenience_la_DEPENDENCIES = @addobjs@ @@ -49,8 +50,9 @@ AM_CFLAGS = @GC_CFLAGS@ check_PROGRAMS = gctest gctest_SOURCES = tests/test.c -gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS) +gctest_LDADD = libgcjgc.la $(THREADLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS) gctest_LDFLAGS = -shared-libgcc +gctest_LINK = $(LINK) $(gctest_LDFLAGS) TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc TESTS = gctest diff --git a/boehm-gc/Makefile.in b/boehm-gc/Makefile.in index 70110d3e194..5b1cfe748a4 100644 --- a/boehm-gc/Makefile.in +++ b/boehm-gc/Makefile.in @@ -70,9 +70,6 @@ am_libgcjgc_la_OBJECTS = allchblk.lo alloc.lo blacklst.lo checksums.lo \ backgraph.lo win32_threads.lo pthread_support.lo \ pthread_stop_world.lo darwin_stop_world.lo $(am__objects_1) libgcjgc_la_OBJECTS = $(am_libgcjgc_la_OBJECTS) -libgcjgc_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libgcjgc_la_LDFLAGS) $(LDFLAGS) -o $@ am__objects_2 = allchblk.lo alloc.lo blacklst.lo checksums.lo \ dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \ headers.lo malloc.lo mallocx.lo mark.lo mark_rts.lo misc.lo \ @@ -86,11 +83,8 @@ libgcjgc_convenience_la_OBJECTS = \ am__dirstamp = $(am__leading_dot)dirstamp am_gctest_OBJECTS = tests/test.$(OBJEXT) gctest_OBJECTS = $(am_gctest_OBJECTS) -gctest_DEPENDENCIES = ./libgcjgc.la $(am__DEPENDENCIES_1) \ +gctest_DEPENDENCIES = libgcjgc.la $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) -gctest_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ - --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(gctest_LDFLAGS) \ - $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include depcomp = am__depfiles_maybe = @@ -291,13 +285,15 @@ sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS) $(UNWINDLIBS) libgcjgc_la_DEPENDENCIES = @addobjs@ libgcjgc_la_LDFLAGS = $(extra_ldflags_libgc) -version-info 1:2:0 -rpath $(toolexeclibdir) +libgcjgc_la_LINK = $(LINK) $(libgcjgc_la_LDFLAGS) libgcjgc_convenience_la_LIBADD = @addobjs@ libgcjgc_convenience_la_DEPENDENCIES = @addobjs@ AM_CXXFLAGS = @GC_CFLAGS@ AM_CFLAGS = @GC_CFLAGS@ gctest_SOURCES = tests/test.c -gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS) +gctest_LDADD = libgcjgc.la $(THREADLIBS) $(UNWINDLIBS) $(EXTRA_TEST_LIBS) gctest_LDFLAGS = -shared-libgcc +gctest_LINK = $(LINK) $(gctest_LDFLAGS) TESTS_ENVIRONMENT = LD_LIBRARY_PATH=../../$(MULTIBUILDTOP)gcc LTCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile \ $(CC) $(DEFS) $(AM_CPPFLAGS) $(CPPFLAGS) \ diff --git a/contrib/ChangeLog b/contrib/ChangeLog index 3174cfff58e..b4627d293b6 100644 --- a/contrib/ChangeLog +++ b/contrib/ChangeLog @@ -1,3 +1,9 @@ +2009-09-10 Iain Sandoe <iain.sandoe@sandoe-acoustics.co.uk> + + PR bootstrap/41245 + * compare-debug: Handle stripping of dwarf debug sections from darwin + mach-o objects. + 2009-09-04 Alexandre Oliva <aoliva@redhat.com> * compare-debug: Grep for blank before dash to avoid grep -e. diff --git a/contrib/compare-debug b/contrib/compare-debug index 6f2b4abfb5c..98c80f93e98 100755 --- a/contrib/compare-debug +++ b/contrib/compare-debug @@ -57,11 +57,19 @@ done trap 'rm -f "$1.$suf1" "$2.$suf2"' 0 1 2 15 -cp "$1" "$1.$suf1" -strip "$1.$suf1" +case `uname -s` in +Darwin) + ld -S -x -r -no_uuid "$1" -o "$1.$suf1" + ld -S -x -r -no_uuid "$2" -o "$2.$suf2" + ;; +*) + cp "$1" "$1.$suf1" + strip "$1.$suf1" -cp "$2" "$2.$suf2" -strip "$2.$suf2" + cp "$2" "$2.$suf2" + strip "$2.$suf2" + ;; +esac if cmp "$1.$suf1" "$2.$suf2"; then status=0 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b47b5d5409c..21bf3159130 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,281 @@ +2009-09-13 Richard Guenther <rguenther@suse.de> + Rafael Avila de Espindola <espindola@google.com> + + * langhooks-def.h (LANG_HOOKS_EH_RUNTIME_TYPE): Define. + (LANG_HOOKS_EH_PERSONALITY): Likewise. + (LANG_HOOKS_INITIALIZER): Adjust. + (lhd_pass_through_t): Declare. + * langhooks.h (struct lang_hooks): Add eh_runtime_type and + eh_personality. + * langhooks.c (lhd_pass_through_t): New function. + * dwarf2out.c (output_call_frame_info, dwarf2out_do_cfi_startproc, + dwarf2out_begin_prologue): Use personality from current_function_decl. + * expr.h (get_personality_function): Declare. + * expr.c (get_personality_function): New function. + (build_personality_function): Likewise. + * libfuncs.h (libfunc_index): Remove LTI_eh_personality. + (eh_personality_libfunc): Remove. + * optabs.c (build_libfunc_function): New function split out from ... + (init_one_libfunc): ... here. + * tree.h (DECL_FUNCTION_PERSONALITY): New. + (tree_function_decl): Add personality. + (lhd_gcc_personality): Declare. + (build_personality_function): Likewise. + * tree.c (gcc_eh_personality_decl): New. + (lhd_gcc_personality): New function. + * except.h (lang_eh_runtime_type): Remove. + (enum eh_personality_kind): New. + (build_personality_function): Declare. + (function_needs_eh_personality): Declare. + * except.c (lang_eh_runtime_type): Remove. + (function_needs_eh_personality): New function. + (add_type_for_runtime): Call lang_hooks.type_for_runtime instead. + (sjlj_emit_function_enter, output_function_exception_table): + Use personality from current_function_decl. + * tree-eh.c (lower_eh_constructs): Set DECL_FUNCTION_PERSONALITY. + * tree-inline.c (tree_can_inline_p): Do not inline across different + EH personalities. + (expand_call_inline): Likewise. Adjust the callers EH personality. + (tree_function_versioning): Copy DECL_FUNCTION_PERSONALITY. + * cgraph.c (cgraph_add_new_function): Set DECL_FUNCTION_PERSONALITY. + * Makefile.in (cgraph.o): Add $(EXCEPT_H) dependency. + (c-parser.o): Likewise + * c-tree.h (c_eh_initialized_p): Remove. + (c_maybe_initialize_eh): Likewise. + * c-decl.c (finish_decl): Don't call c_maybe_initialize_eh. + (finish_decl): Don't call c_maybe_initialize_eh. + (c_eh_initialized_p): Remove. + (c_maybe_initialize_eh): Likewise. + * c-parser.c (c_parser_omp_construct): Likewise. + (c_parse_file): Initialize exception handling. + +2009-09-13 Kai Tietz <kai.tietz@onevision.com> + + * config.gcc (tm_file): Remove i386/biarch32.h + for i?86-w64-mingw* case. + (i?86-*-mingw* andx86_64-*-mingw*): Add multilib + support. + * config.host: Set for x64 mingw the option + use_long_long_for_widest_fast_int to yes. + +2009-09-13 Eric Botcazou <ebotcazou@adacore.com> + + * tree.h (DECL_IGNORED_P): Document further effect for FUNCTION_DECL. + * dbxout.c (dbxout_function_end): Do not test DECL_IGNORED_P. + (dbxout_begin_function): Likewise. + * final.c (dwarf2_debug_info_emitted_p): New predicate. + (final_start_function): Do not emit debug info if DECL_IGNORED_P is + set on the function. + (final_end_function): Likewise. + (final_scan_insn): Likewise. + (rest_of_handle_final): Likewise. + * varasm.c (assemble_start_function): Likewise. + * config/rs6000/xcoff.h (ASM_DECLARE_FUNCTION_NAME): Likewise. + +2009-09-12 Jason Merrill <jason@redhat.com> + + * dbgcnt.c (dbg_cnt_process_single_pair): constify. + * opts.c (common_handle_option): constify. + +2009-09-12 Gerald Pfeifer <gerald@pfeifer.com> + + * doc/install.texi (avr): Remove obsolete reference site. + +2009-09-12 Gerald Pfeifer <gerald@pfeifer.com> + + * doc/install.texi (Binaries): Adjust AIX link. + +2009-09-12 Akim Demaille <demaille@gostai.com> + + * doc/invoke.texi (-fstrict-aliasing): Correct two examples. + Use an imperative sentence. + +2009-09-11 Richard Henderson <rth@redhat.com> + + * gsstruct.def (DEFGSSTRUCT): Remove printable-name argument; add + structure-name and has-tree-operands arguments; update all entries. + * gimple.def (DEFGSCODE): Replace 3rd argument with GSS_symbol; + update all entries. + * gimple.c (gimple_ops_offset_): Use HAS_TREE_OP argument. + (gsstruct_code_size): New. + (gss_for_code_): New. + (gss_for_code): Remove. + (gimple_size): Rewrite using gsstruct_code_size. + (gimple_statement_structure): Move to gimple.h. + * gimple.h (gimple_ops_offset_, gss_for_code_): Declare. + (gss_for_code, gimple_statement_structure): New. + (gimple_ops): Use new arrays; tidy. + +2009-09-11 John David Anglin <dave.anglin@nrc-cnrc.gc.ca> + + * config/pa/predicates.md (symbolic_operand): Require a CONST symbolic + operand to be a PLUS expression. + * config/pa/pa.c (pa_secondary_reload): Likewise. + +2009-09-11 Jakub Jelinek <jakub@redhat.com> + + * combine.c (propagate_for_debug_subst): Call wrap_constant on top. + + * print-rtl.c (print_rtx): Use JUMP_LABEL (in_rtx) instead of + XEXP (in_rtx, 8). + +2009-09-11 Bernd Schmidt <bernd.schmidt@analog.com> + + From Jie Zhang <jie.zhang@analog.com>: + * doc/extend.texi (node Function Attributes): Document l2 + function attribute. + (node Blackfin Variable Attributes): Document l2 variable attributes. + +2009-09-11 Loren J. Rittle <ljrittle@acm.org> + + * config.gcc (*-*-freebsd*): Enable default_use_cxa_atexit + to match the system compiler's configuration at inflection point. + Add comment to remark a remaining difference with system compiler. + + * configure.ac (*-*-freebsd*): Enable check for __stack_chk_fail. + * configure: Regenerate. + +2009-09-11 Bernd Schmidt <bernd.schmidt@analog.com> + + From Jie Zhang <jie.zhang@analog.com>: + * config/bfin/bfin.c (bfin_expand_call): Handle L2 functions. + (bfin_handle_l2_attribute): New. + (bfin_attribute_table): Add l2 attribute. + +2009-09-11 Michael Matz <matz@suse.de> + + PR middle-end/41275 + * tree-inline.c (remap_decls): Don't put DECL_EXTERNAL decls + on the local_decls list. + +2009-09-11 Alexandre Oliva <aoliva@redhat.com> + + PR debug/41276 + PR debug/41307 + * cselib.c (cselib_expand_value_rtx_cb): Document callback + interface. + (cselib_expand_value_rtx_1): Use callback for SUBREGs. Adjust + for VALUEs, to implement the documented interface. + * var-tracking.c (vt_expand_loc_callback): Handle SUBREGs. + Adjust for VALUEs and anything else, to implement the + documented interface. + +2009-09-10 Nathan Froyd <froydnj@codesourcery.com> + + * config/rs6000/rs6000.h (DATA_ALIGNMENT): Check that we are dealing + with actual SPE/paired vector modes before using 64-bit alignment. + Check that TYPE is a REAL_TYPE for TARGET_E500_DOUBLE. + +2009-09-10 DJ Delorie <dj@redhat.com> + + * config/mep/mep.md (eh_epilogue): Defer until after epilogue is + emitted. + + * config/mep/mep.h (LEGITIMATE_CONSTANT_P): New. + * config/mep/mep.c (mep_legitimate_constant_p): New. + * config/mep/mep-protos.h: Prototype it. + +2009-09-10 Richard Henderson <rth@redhat.com> + + * print-rtl.c (print_rtx): Fix JUMP_LABEL index. + +2009-09-10 Jason Merrill <jason@redhat.com> + + * tree.c (chain_index): New fn. + * tree.h: Declare it. + +2009-09-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + * config/sol2-c.c (cmn_err_length_specs): Initialize + scalar_identity_flag. + +2009-09-10 Richard Henderson <rth@redhat.com> + + * tree.h (struct tree_decl_common): Move align member earlier; + move label_decl_uid member ... + (struct tree_label_decl): ... here. + (LABEL_DECL_UID): Update to match. + + * tree-cfg.c (dump_function_to_file): Dump eh tree with TDF_EH, + not TDF_DETAILS. + + * tree-cfg.c (gimple_redirect_edge_and_branch): Do + gimple_try_redirect_by_replacing_jump test after no-op and EH tests. + + * tree-cfg.c (split_edge_bb_loc): Don't disallow placement at + dest_prev if the edge is complex. + + * tree-cfg.c (is_ctrl_stmt): Use a switch. + + * tree-cfg.c (gimple_can_merge_blocks_p): Move label and + loop latch tests earlier. + + * gimple-iterator.c (gimple_find_edge_insert_loc): Insert + before GIMPLE_RETURN, not after its predecessor; insert + before GIMPLE_RESX. + + * gimple-iterator.c (gimple_find_edge_insert_loc): Use + gimple_seq_empty_p to test for no PHI nodes. + * tree-cfg.c (split_critical_edges): Likewise. + + * c-common.h (c_dialect_cxx, c_dialect_objc): Boolify. + +2009-09-10 Hariharan Sandanagobalane <hariharan@picochip.com> + + * final.c (shorten_branches) : Ignore DEBUG_INSN_P instructions + introduced by the VTA branch merge. + +2009-09-10 Uros Bizjak <ubizjak@gmail.com> + + * ira-conflicts.c: Use fputs or putc instead of fprintf + where appropriate. + * cfg.c: Ditto. + * toplev.c: Ditto. + * tree-switch-conversion.c: Ditto. + +2009-09-10 Hariharan Sandanagobalane <hariharan@picochip.com> + + * config/picochip/picochip.c : Ignore DEBUG_INSN_P instructions + introduced by the VTA branch merge. + +2009-09-10 Uros Bizjak <ubizjak@gmail.com> + + Revert: + 2009-09-09 Uros Bizjak <ubizjak@gmail.com> + + PR rtl-optimization/39779 + * expr.c (convert_modes): Return when mode == oldmode after + CONST_INTs are processed. + +2009-09-10 Nick Clifton <nickc@redhat.com> + + * config/mep/mep.c (mep_encode_section_info): Copy weakness + attribute and referring decl when creating renamed symbol. + +2009-09-10 Richard Guenther <rguenther@suse.de> + + PR middle-end/41257 + * cgraphunit.c (cgraph_emit_thunks): Emit thunks only for + reachable nodes. + (cgraph_finalize_compilation_unit): Compute reachability + before emitting thunks. Properly process aliases before + possibly removing unreachable nodes. + +2009-09-10 Richard Guenther <rguenther@suse.de> + + PR middle-end/41254 + * tree.c (struct free_lang_data_d): Add worklist member. + (find_decls_types_r): Push onto the worklist instead of recursing. + Handle TREE_BINFOs properly. + (find_decls_types): New function wrapped around find_decls_types_r + to process the worklist. + (find_decls_types_in_eh_region): Use it. + (find_decls_types_in_node): Likewise. + (find_decls_types_in_var): Likewise. + (free_lang_data_in_cgraph): Likewise. Free the worklist. + * tree.h (RECORD_OR_UNION_TYPE_P): New. + (AGGREGATE_TYPE_P): Adjust. + 2009-09-09 Jason Merrill <jason@redhat.com> * configure.ac: Check glibc version even if we have an in-tree diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 16c9f7624db..5e1b5669afd 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20090910 +20090914 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index a5b85e339a3..32149e19ee8 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1934,7 +1934,7 @@ c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ c-parser.o : c-parser.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(GGC_H) $(TIMEVAR_H) $(C_TREE_H) $(INPUT_H) $(FLAGS_H) $(TOPLEV_H) output.h \ $(CPPLIB_H) gt-c-parser.h $(RTL_H) langhooks.h $(C_COMMON_H) $(C_PRAGMA_H) \ - vec.h $(TARGET_H) $(CGRAPH_H) $(PLUGIN_H) + vec.h $(TARGET_H) $(CGRAPH_H) $(PLUGIN_H) $(EXCEPT_H) srcextra: gcc.srcextra lang.srcextra @@ -2812,7 +2812,7 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ langhooks.h $(TOPLEV_H) $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \ gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \ - $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h + $(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) value-prof.h $(EXCEPT_H) cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h $(TREE_INLINE_H) $(TOPLEV_H) $(FLAGS_H) $(GGC_H) \ $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \ diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 9ebc3d22edf..7d4d8aad293 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,19 @@ +2009-09-13 Richard Guenther <rguenther@suse.de> + Rafael Avila de Espindola <espindola@google.com> + + * gcc-interface/misc.c (gnat_init_gcc_eh): Do not set + lang_eh_runtime_type. + (LANG_HOOKS_EH_PERSONALITY): Define. + (gnat_eh_personality_decl): New. + (gnat_eh_personality): Likewise. + * Make-lang.in (misc.o): Add gt-ada-misc.h dependency. + * config-lang.in (gtfiles): Add misc.c. + +2009-09-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + + PR ada/18302 + * gcc-interface/Make-lang.in (check-acats): Export rootme, EXPECT. + 2009-09-08 Eric Botcazou <ebotcazou@adacore.com> * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Array_Subtype>: Tidy diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in index 86707e0313b..163274c4332 100644 --- a/gcc/ada/gcc-interface/Make-lang.in +++ b/gcc/ada/gcc-interface/Make-lang.in @@ -841,6 +841,8 @@ check_acats_targets = $(patsubst %,check-acats%, 0 1 2) check-acats: @test -d $(ACATSDIR) || mkdir -p $(ACATSDIR); \ + rootme=`${PWD_COMMAND}`; export rootme; \ + EXPECT=$(EXPECT); export EXPECT; \ if [ -z "$(CHAPTERS)" ] && [ "$(filter -j, $(MFLAGS))" = "-j" ]; \ then \ $(MAKE) $(check_acats_targets); \ @@ -1070,7 +1072,8 @@ ada/misc.o : ada/gcc-interface/misc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(LANGHOOKS_DEF_H) opts.h options.h $(TREE_INLINE_H) \ ada/gcc-interface/ada.h ada/adadecode.h ada/types.h ada/atree.h \ ada/elists.h ada/namet.h ada/nlists.h ada/stringt.h ada/uintp.h ada/fe.h \ - ada/sinfo.h ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h + ada/sinfo.h ada/einfo.h $(ADA_TREE_H) ada/gcc-interface/gigi.h \ + gt-ada-misc.h $(COMPILER) -c $(ALL_COMPILERFLAGS) -I.. $(ALL_CPPFLAGS) $< -o $@ ada/targtyps.o : ada/gcc-interface/targtyps.c $(CONFIG_H) $(SYSTEM_H) \ diff --git a/gcc/ada/gcc-interface/config-lang.in b/gcc/ada/gcc-interface/config-lang.in index 58253989290..b4a28be14c7 100644 --- a/gcc/ada/gcc-interface/config-lang.in +++ b/gcc/ada/gcc-interface/config-lang.in @@ -32,7 +32,7 @@ boot_language_boot_flags='ADAFLAGS="$(BOOT_ADAFLAGS)"' compilers="gnat1\$(exeext)" -gtfiles="\$(srcdir)/ada/gcc-interface/ada-tree.h \$(srcdir)/ada/gcc-interface/gigi.h \$(srcdir)/ada/gcc-interface/decl.c \$(srcdir)/ada/gcc-interface/trans.c \$(srcdir)/ada/gcc-interface/utils.c" +gtfiles="\$(srcdir)/ada/gcc-interface/ada-tree.h \$(srcdir)/ada/gcc-interface/gigi.h \$(srcdir)/ada/gcc-interface/decl.c \$(srcdir)/ada/gcc-interface/trans.c \$(srcdir)/ada/gcc-interface/utils.c \$(srcdir)/ada/gcc-interface/misc.c" outputs="ada/gcc-interface/Makefile ada/Makefile" diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index f39a60eb4cc..261351f840c 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -79,6 +79,7 @@ static void gnat_parse_file (int); static void internal_error_function (const char *, va_list *); static tree gnat_type_max_size (const_tree); static void gnat_get_subrange_bounds (const_tree, tree *, tree *); +static tree gnat_eh_personality (void); /* Definitions for our language-specific hooks. */ @@ -129,7 +130,9 @@ static void gnat_get_subrange_bounds (const_tree, tree *, tree *); #undef LANG_HOOKS_ATTRIBUTE_TABLE #define LANG_HOOKS_ATTRIBUTE_TABLE gnat_internal_attribute_table #undef LANG_HOOKS_BUILTIN_FUNCTION -#define LANG_HOOKS_BUILTIN_FUNCTION gnat_builtin_function +#define LANG_HOOKS_BUILTIN_FUNCTION gnat_builtin_function +#undef LANG_HOOKS_EH_PERSONALITY +#define LANG_HOOKS_EH_PERSONALITY gnat_eh_personality struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; @@ -431,11 +434,7 @@ gnat_init_gcc_eh (void) right exception regions. */ using_eh_for_cleanups (); - eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS - ? "__gnat_eh_personality_sj" - : "__gnat_eh_personality"); lang_eh_type_covers = gnat_eh_type_covers; - lang_eh_runtime_type = gnat_return_tree; default_init_unwind_resume_libfunc (); /* Turn on -fexceptions and -fnon-call-exceptions. The first one triggers @@ -811,3 +810,19 @@ fp_size_to_prec (int size) gcc_unreachable (); } + +static GTY(()) tree gnat_eh_personality_decl; + +static tree +gnat_eh_personality (void) +{ + if (!gnat_eh_personality_decl) + gnat_eh_personality_decl + = build_personality_function (USING_SJLJ_EXCEPTIONS + ? "__gnat_eh_personality_sj" + : "__gnat_eh_personality"); + + return gnat_eh_personality_decl; +} + +#include "gt-ada-misc.h" diff --git a/gcc/c-common.h b/gcc/c-common.h index d372e70631e..9b7905b5a30 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -360,8 +360,8 @@ c_language_kind; front end. For "ObjC features" or "not C++" use the macros. */ extern c_language_kind c_language; -#define c_dialect_cxx() (c_language & clk_cxx) -#define c_dialect_objc() (c_language & clk_objc) +#define c_dialect_cxx() ((c_language & clk_cxx) != 0) +#define c_dialect_objc() ((c_language & clk_objc) != 0) /* Information about a statement tree. */ diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 1bc97914f96..ed8863dddd9 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -92,9 +92,6 @@ tree pending_invalid_xref; /* File and line to appear in the eventual error message. */ location_t pending_invalid_xref_location; -/* True means we've initialized exception handling. */ -bool c_eh_initialized_p; - /* The file and line that the prototype came from if this is an old-style definition; used for diagnostics in store_parm_decls_oldstyle. */ @@ -2365,7 +2362,8 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) TREE_USED (olddecl) = 1; /* Copy most of the decl-specific fields of NEWDECL into OLDDECL. - But preserve OLDDECL's DECL_UID and DECL_CONTEXT. */ + But preserve OLDDECL's DECL_UID, DECL_CONTEXT and + DECL_ARGUMENTS (if appropriate). */ { unsigned olddecl_uid = DECL_UID (olddecl); tree olddecl_context = DECL_CONTEXT (olddecl); @@ -4043,23 +4041,6 @@ start_decl (struct c_declarator *declarator, struct c_declspecs *declspecs, return tem; } -/* Initialize EH if not initialized yet and exceptions are enabled. */ - -void -c_maybe_initialize_eh (void) -{ - if (!flag_exceptions || c_eh_initialized_p) - return; - - c_eh_initialized_p = true; - eh_personality_libfunc - = init_one_libfunc (USING_SJLJ_EXCEPTIONS - ? "__gcc_personality_sj0" - : "__gcc_personality_v0"); - default_init_unwind_resume_libfunc (); - using_eh_for_cleanups (); -} - /* Finish processing of a declaration; install its initial value. If ORIGTYPE is not NULL_TREE, it is the original type of INIT. @@ -4360,9 +4341,6 @@ finish_decl (tree decl, location_t init_loc, tree init, TREE_USED (decl) = 1; TREE_USED (cleanup_decl) = 1; - /* Initialize EH, if we've been told to do so. */ - c_maybe_initialize_eh (); - push_cleanup (decl, cleanup, false); } } diff --git a/gcc/c-parser.c b/gcc/c-parser.c index 43b0c8ce38c..ddb81e16504 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see #include "target.h" #include "cgraph.h" #include "plugin.h" +#include "except.h" /* Initialization routine for this file. */ @@ -8489,12 +8490,6 @@ c_parser_omp_construct (c_parser *parser) p_kind = c_parser_peek_token (parser)->pragma_kind; c_parser_consume_pragma (parser); - /* For all constructs below except #pragma omp atomic - MUST_NOT_THROW catch handlers are needed when exceptions - are enabled. */ - if (p_kind != PRAGMA_OMP_ATOMIC) - c_maybe_initialize_eh (); - switch (p_kind) { case PRAGMA_OMP_ATOMIC: @@ -8607,6 +8602,13 @@ c_parse_file (void) the_parser = GGC_NEW (c_parser); *the_parser = tparser; + /* Initialize EH, if we've been told to do so. */ + if (flag_exceptions) + { + default_init_unwind_resume_libfunc (); + using_eh_for_cleanups (); + } + c_parser_translation_unit (the_parser); the_parser = NULL; } diff --git a/gcc/c-tree.h b/gcc/c-tree.h index 502e6efd152..5c1ccb537d5 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -427,7 +427,6 @@ extern struct c_spot_bindings *c_get_switch_bindings (void); extern void c_release_switch_bindings (struct c_spot_bindings *); extern bool c_check_switch_jump_warnings (struct c_spot_bindings *, location_t, location_t); -extern void c_maybe_initialize_eh (void); extern void finish_decl (tree, location_t, tree, tree, tree); extern tree finish_enum (tree, tree, tree); extern void finish_function (void); @@ -589,9 +588,6 @@ extern int system_header_p; extern bool c_override_global_bindings_to_false; -/* True means we've initialized exception handling. */ -extern bool c_eh_initialized_p; - /* In c-decl.c */ extern void c_finish_incomplete_decl (tree); extern void c_write_global_declarations (void); diff --git a/gcc/cfg.c b/gcc/cfg.c index 9c41930a36f..550f8f13d3b 100644 --- a/gcc/cfg.c +++ b/gcc/cfg.c @@ -546,10 +546,10 @@ dump_bb_info (basic_block bb, bool header, bool footer, int flags, /* Both maybe_hot_bb_p & probably_never_executed_bb_p functions crash without cfun. */ if (cfun && maybe_hot_bb_p (bb)) - fprintf (file, ", maybe hot"); + fputs (", maybe hot", file); if (cfun && probably_never_executed_bb_p (bb)) - fprintf (file, ", probably never executed"); - fprintf (file, ".\n"); + fputs (", probably never executed", file); + fputs (".\n", file); fprintf (file, "%sPredecessors: ", prefix); FOR_EACH_EDGE (e, ei, bb->preds) @@ -559,7 +559,7 @@ dump_bb_info (basic_block bb, bool header, bool footer, int flags, && (bb->flags & BB_RTL) && df) { - fprintf (file, "\n"); + putc ('\n', file); df_dump_top (bb, file); } } @@ -574,7 +574,7 @@ dump_bb_info (basic_block bb, bool header, bool footer, int flags, && (bb->flags & BB_RTL) && df) { - fprintf (file, "\n"); + putc ('\n', file); df_dump_bottom (bb, file); } } @@ -615,11 +615,11 @@ dump_reg_info (FILE *file) fprintf (file, "; set %d time%s", DF_REG_DEF_COUNT (i), (DF_REG_DEF_COUNT (i) == 1) ? "" : "s"); if (regno_reg_rtx[i] != NULL && REG_USERVAR_P (regno_reg_rtx[i])) - fprintf (file, "; user var"); + fputs ("; user var", file); if (REG_N_DEATHS (i) != 1) fprintf (file, "; dies in %d places", REG_N_DEATHS (i)); if (REG_N_CALLS_CROSSED (i) == 1) - fprintf (file, "; crosses 1 call"); + fputs ("; crosses 1 call", file); else if (REG_N_CALLS_CROSSED (i)) fprintf (file, "; crosses %d calls", REG_N_CALLS_CROSSED (i)); if (REG_FREQ_CALLS_CROSSED (i)) @@ -643,8 +643,8 @@ dump_reg_info (FILE *file) } if (regno_reg_rtx[i] != NULL && REG_POINTER (regno_reg_rtx[i])) - fprintf (file, "; pointer"); - fprintf (file, ".\n"); + fputs ("; pointer", file); + fputs (".\n", file); } } @@ -691,7 +691,7 @@ dump_edge_info (FILE *file, edge e, int do_succ) if (e->count) { - fprintf (file, " count:"); + fputs (" count:", file); fprintf (file, HOST_WIDEST_INT_PRINT_DEC, e->count); } @@ -904,24 +904,24 @@ dump_cfg_bb_info (FILE *file, basic_block bb) if (bb->flags & (1 << i)) { if (first) - fprintf (file, " ("); + fputs (" (", file); else - fprintf (file, ", "); + fputs (", ", file); first = false; - fprintf (file, bb_bitnames[i]); + fputs (bb_bitnames[i], file); } if (!first) - fprintf (file, ")"); - fprintf (file, "\n"); + putc (')', file); + putc ('\n', file); - fprintf (file, "Predecessors: "); + fputs ("Predecessors: ", file); FOR_EACH_EDGE (e, ei, bb->preds) dump_edge_info (file, e, 0); fprintf (file, "\nSuccessors: "); FOR_EACH_EDGE (e, ei, bb->succs) dump_edge_info (file, e, 1); - fprintf (file, "\n\n"); + fputs ("\n\n", file); } /* Dumps a brief description of cfg to FILE. */ diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 2f5bd2a34a6..75447be839e 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -84,6 +84,7 @@ The callgraph: #include "tree-dump.h" #include "tree-flow.h" #include "value-prof.h" +#include "except.h" static void cgraph_node_remove_callers (struct cgraph_node *node); static inline void cgraph_edge_remove_caller (struct cgraph_edge *e); @@ -1953,6 +1954,12 @@ cgraph_add_new_function (tree fndecl, bool lowered) current_function_decl = NULL; break; } + + /* Set a personality if required and we already passed EH lowering. */ + if (lowered + && (function_needs_eh_personality (DECL_STRUCT_FUNCTION (fndecl)) + == eh_personality_lang)) + DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality (); } /* Return true if NODE can be made local for API change. diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 0acc4723f07..5551c721762 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1036,7 +1036,8 @@ cgraph_emit_thunks (void) emitted, but we cannot know that until the inliner and other IPA passes have run (see the sequencing of the call to cgraph_mark_functions_to_output in cgraph_optimize). */ - if (!DECL_EXTERNAL (n->decl)) + if (n->reachable + && !DECL_EXTERNAL (n->decl)) lang_hooks.callgraph.emit_associated_thunks (n->decl); } } @@ -1047,35 +1048,45 @@ cgraph_emit_thunks (void) void cgraph_finalize_compilation_unit (void) { + timevar_push (TV_CGRAPH); + /* Do not skip analyzing the functions if there were errors, we miss diagnostics for following functions otherwise. */ /* Emit size functions we didn't inline. */ finalize_size_functions (); - /* Emit thunks, if needed. */ - if (lang_hooks.callgraph.emit_associated_thunks) - cgraph_emit_thunks (); - /* Call functions declared with the "constructor" or "destructor" attribute. */ cgraph_build_cdtor_fns (); + /* Mark alias targets necessary and emit diagnostics. */ + finish_aliases_1 (); + if (!quiet_flag) { fprintf (stderr, "\nAnalyzing compilation unit\n"); fflush (stderr); } + /* Gimplify and lower all functions, compute reachability and + remove unreachable nodes. */ + cgraph_analyze_functions (); + + /* Emit thunks for reachable nodes, if needed. */ + if (lang_hooks.callgraph.emit_associated_thunks) + cgraph_emit_thunks (); + /* Mark alias targets necessary and emit diagnostics. */ finish_aliases_1 (); - /* Gimplify and lower all functions. */ - timevar_push (TV_CGRAPH); + /* Gimplify and lower thunks. */ cgraph_analyze_functions (); - timevar_pop (TV_CGRAPH); + /* Finally drive the pass manager. */ cgraph_optimize (); + + timevar_pop (TV_CGRAPH); } diff --git a/gcc/combine.c b/gcc/combine.c index bc61fbedcf4..3437216ed51 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -2314,7 +2314,7 @@ propagate_for_debug_subst (rtx *loc, void *data) to = simplify_gen_subreg (GET_MODE (x), to, GET_MODE (from), SUBREG_BYTE (x)); } - *loc = to; + *loc = wrap_constant (GET_MODE (x), to); pair->changed = true; return -1; } diff --git a/gcc/config.gcc b/gcc/config.gcc index 6a680a0b094..00025638ceb 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -373,12 +373,6 @@ then fi case ${target} in -i[34567]86-w64-*) - tm_file="i386/biarch32.h ${tm_file}" - ;; -esac - -case ${target} in i[34567]86-*-*) if test "x$enable_cld" = xyes; then tm_defines="${tm_defines} USE_IX86_CLD=1" @@ -478,6 +472,13 @@ case ${target} in ;; esac fbsd_tm_file="${fbsd_tm_file} freebsd-spec.h freebsd.h freebsd-stdint.h" + case ${target} in + *-*-freebsd[345].*) + :;; + *) + default_use_cxa_atexit=yes;; + esac + # need_64bit_hwint=yes # system compiler has this for all arch! use_gcc_stdint=wrap ;; *-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu) @@ -1312,11 +1313,35 @@ i[34567]86-*-pe | i[34567]86-*-cygwin*) i[34567]86-*-mingw* | x86_64-*-mingw*) tm_file="${tm_file} i386/unix.h i386/bsd.h i386/gas.h dbxcoff.h i386/cygming.h i386/mingw32.h" xm_file=i386/xm-mingw32.h + case ${target} in + x86_64-*-* | *-w64-*) + need_64bit_hwint=yes + ;; + *) + ;; + esac # This makes the logic if mingw's or the w64 feature set has to be used case ${target} in *-w64-*) tm_file="${tm_file} i386/mingw-w64.h" tmake_file="${tmake_file} i386/t-mingw-w64" + if test x$enable_targets = xall; then + tm_defines="${tm_defines} TARGET_BI_ARCH=1" + case X"${with_cpu}" in + Xgeneric|Xatom|Xcore2|Xnocona|Xx86-64|Xamdfam10|Xbarcelona|Xk8|Xopteron|Xathlon64|Xathlon-fx) + ;; + X) + if test x$with_cpu_64 = x; then + with_cpu_64=generic + fi + ;; + *) + echo "Unsupported CPU used in --with-cpu=$with_cpu, supported values:" 1>&2 + echo "generic atom core2 nocona x86-64 amdfam10 barcelona k8 opteron athlon64 athlon-fx" 1>&2 + exit 1 + ;; + esac + fi ;; *) tmake_file="${tmake_file} i386/t-mingw32" diff --git a/gcc/config.host b/gcc/config.host index a8ec32455aa..4affcb06b17 100644 --- a/gcc/config.host +++ b/gcc/config.host @@ -207,7 +207,14 @@ case ${host} in host_xmake_file="${host_xmake_file} i386/x-cygwin" host_exeext=.exe ;; - i[34567]86-*-mingw32* | x86_64-*-mingw*) + i[34567]86-*-mingw32*) + host_xm_file=i386/xm-mingw32.h + host_xmake_file="${host_xmake_file} i386/x-mingw32" + host_exeext=.exe + out_host_hook_obj=host-mingw32.o + ;; + x86_64-*-mingw*) + use_long_long_for_widest_fast_int=yes host_xm_file=i386/xm-mingw32.h host_xmake_file="${host_xmake_file} i386/x-mingw32" host_exeext=.exe diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 28406150eea..ed51006fd77 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -2255,28 +2255,38 @@ bfin_expand_call (rtx retval, rtx fnaddr, rtx callarg1, rtx cookie, int sibcall) if (TARGET_FDPIC) { - int caller_has_l1_text, callee_has_l1_text; + int caller_in_sram, callee_in_sram; - caller_has_l1_text = callee_has_l1_text = 0; + /* 0 is not in sram, 1 is in L1 sram, 2 is in L2 sram. */ + caller_in_sram = callee_in_sram = 0; if (lookup_attribute ("l1_text", DECL_ATTRIBUTES (cfun->decl)) != NULL_TREE) - caller_has_l1_text = 1; + caller_in_sram = 1; + else if (lookup_attribute ("l2", + DECL_ATTRIBUTES (cfun->decl)) != NULL_TREE) + caller_in_sram = 2; if (GET_CODE (callee) == SYMBOL_REF - && SYMBOL_REF_DECL (callee) && DECL_P (SYMBOL_REF_DECL (callee)) - && lookup_attribute - ("l1_text", - DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE) - callee_has_l1_text = 1; + && SYMBOL_REF_DECL (callee) && DECL_P (SYMBOL_REF_DECL (callee))) + { + if (lookup_attribute + ("l1_text", + DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE) + callee_in_sram = 1; + else if (lookup_attribute + ("l2", + DECL_ATTRIBUTES (SYMBOL_REF_DECL (callee))) != NULL_TREE) + callee_in_sram = 2; + } if (GET_CODE (callee) != SYMBOL_REF || bfin_longcall_p (callee, INTVAL (cookie)) || (GET_CODE (callee) == SYMBOL_REF && !SYMBOL_REF_LOCAL_P (callee) && TARGET_INLINE_PLT) - || caller_has_l1_text != callee_has_l1_text - || (caller_has_l1_text && callee_has_l1_text + || caller_in_sram != callee_in_sram + || (caller_in_sram && callee_in_sram && (GET_CODE (callee) != SYMBOL_REF || !SYMBOL_REF_LOCAL_P (callee)))) { @@ -5663,6 +5673,45 @@ bfin_handle_l1_data_attribute (tree *node, tree name, tree ARG_UNUSED (args), return NULL_TREE; } +/* Handle a "l2" attribute; arguments as in struct attribute_spec.handler. */ + +static tree +bfin_handle_l2_attribute (tree *node, tree ARG_UNUSED (name), + tree ARG_UNUSED (args), int ARG_UNUSED (flags), + bool *no_add_attrs) +{ + tree decl = *node; + + if (TREE_CODE (decl) == FUNCTION_DECL) + { + if (DECL_SECTION_NAME (decl) != NULL_TREE + && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), + ".l2.text") != 0) + { + error ("section of %q+D conflicts with previous declaration", + decl); + *no_add_attrs = true; + } + else + DECL_SECTION_NAME (decl) = build_string (9, ".l2.text"); + } + else if (TREE_CODE (decl) == VAR_DECL) + { + if (DECL_SECTION_NAME (decl) != NULL_TREE + && strcmp (TREE_STRING_POINTER (DECL_SECTION_NAME (decl)), + ".l2.data") != 0) + { + error ("section of %q+D conflicts with previous declaration", + decl); + *no_add_attrs = true; + } + else + DECL_SECTION_NAME (decl) = build_string (9, ".l2.data"); + } + + return NULL_TREE; +} + /* Table of valid machine attributes. */ static const struct attribute_spec bfin_attribute_table[] = { @@ -5679,6 +5728,7 @@ static const struct attribute_spec bfin_attribute_table[] = { "l1_data", 0, 0, true, false, false, bfin_handle_l1_data_attribute }, { "l1_data_A", 0, 0, true, false, false, bfin_handle_l1_data_attribute }, { "l1_data_B", 0, 0, true, false, false, bfin_handle_l1_data_attribute }, + { "l2", 0, 0, true, false, false, bfin_handle_l2_attribute }, { NULL, 0, 0, false, false, false, NULL } }; diff --git a/gcc/config/mep/mep-protos.h b/gcc/config/mep/mep-protos.h index a4de754bbd9..e53ca79639c 100644 --- a/gcc/config/mep/mep-protos.h +++ b/gcc/config/mep/mep-protos.h @@ -48,6 +48,7 @@ extern void mep_split_wide_move (rtx *, enum machine_mode); #ifdef RTX_CODE extern bool mep_expand_setcc (rtx *); extern rtx mep_expand_cbranch (rtx *); +extern bool mep_legitimate_constant_p (rtx); #endif extern const char *mep_emit_cbranch (rtx *, int); extern void mep_expand_call (rtx *, int); diff --git a/gcc/config/mep/mep.c b/gcc/config/mep/mep.c index efed4b6caf6..6ff6405c571 100644 --- a/gcc/config/mep/mep.c +++ b/gcc/config/mep/mep.c @@ -1211,6 +1211,20 @@ mep_multi_slot (rtx x) } +bool +mep_legitimate_constant_p (rtx x) +{ + /* We can't convert symbol values to gp- or tp-rel values after + reload, as reload might have used $gp or $tp for other + purposes. */ + if (GET_CODE (x) == SYMBOL_REF && (reload_in_progress || reload_completed)) + { + char e = mep_section_tag (x); + return (e != 't' && e != 'b'); + } + return 1; +} + /* Be careful not to use macros that need to be compiled one way for strict, and another way for not-strict, like REG_OK_FOR_BASE_P. */ @@ -4564,6 +4578,8 @@ mep_encode_section_info (tree decl, rtx rtl, int first) idp = get_identifier (newname); XEXP (rtl, 0) = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp)); + SYMBOL_REF_WEAK (XEXP (rtl, 0)) = DECL_WEAK (decl); + SET_SYMBOL_REF_DECL (XEXP (rtl, 0), decl); switch (encoding) { diff --git a/gcc/config/mep/mep.h b/gcc/config/mep/mep.h index cb09c308d50..39837dfc329 100644 --- a/gcc/config/mep/mep.h +++ b/gcc/config/mep/mep.h @@ -599,7 +599,8 @@ typedef struct #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) -#define LEGITIMATE_CONSTANT_P(X) 1 +#define LEGITIMATE_CONSTANT_P(X) \ + mep_legitimate_constant_p(X) #define SELECT_CC_MODE(OP, X, Y) CCmode diff --git a/gcc/config/mep/mep.md b/gcc/config/mep/mep.md index 20beef6b438..773a9a0aa14 100644 --- a/gcc/config/mep/mep.md +++ b/gcc/config/mep/mep.md @@ -2192,7 +2192,7 @@ (use (reg:SI LP_REGNO))] "" "#" - "reload_completed" + "epilogue_completed" [(const_int 1)] "mep_emit_eh_epilogue (operands); DONE;" [(set_attr "slot" "multi")]) diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 4355d0a2ac7..65a07d9eb93 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -5793,9 +5793,10 @@ pa_secondary_reload (bool in_p, rtx x, enum reg_class rclass, break; case CONST: op = XEXP (x, 0); - is_symbolic = (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF - && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0))) - || GET_CODE (XEXP (op, 0)) == LABEL_REF) + is_symbolic = (GET_CODE (op) == PLUS + && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF + && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0))) + || GET_CODE (XEXP (op, 0)) == LABEL_REF) && GET_CODE (XEXP (op, 1)) == CONST_INT); break; default: diff --git a/gcc/config/pa/predicates.md b/gcc/config/pa/predicates.md index 1fc921e9b1b..0f0a42488b9 100644 --- a/gcc/config/pa/predicates.md +++ b/gcc/config/pa/predicates.md @@ -73,9 +73,10 @@ return 1; case CONST: op = XEXP (op, 0); - return (((GET_CODE (XEXP (op, 0)) == SYMBOL_REF - && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0))) - || GET_CODE (XEXP (op, 0)) == LABEL_REF) + return (GET_CODE (op) == PLUS + && ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF + && !SYMBOL_REF_TLS_MODEL (XEXP (op, 0))) + || GET_CODE (XEXP (op, 0)) == LABEL_REF) && GET_CODE (XEXP (op, 1)) == CONST_INT); default: return 0; diff --git a/gcc/config/picochip/picochip.c b/gcc/config/picochip/picochip.c index ecec1f7121e..5155e7695ad 100644 --- a/gcc/config/picochip/picochip.c +++ b/gcc/config/picochip/picochip.c @@ -2920,7 +2920,7 @@ reorder_var_tracking_notes (void) { next = NEXT_INSN (insn); - if (INSN_P (insn)) + if (NONDEBUG_INSN_P (insn)) { /* Emit queued up notes before the first instruction of a bundle. */ if (GET_MODE (insn) == TImode) @@ -3016,7 +3016,7 @@ picochip_reorg (void) INSN_LOCATOR (insn1) = vliw_insn_location; } /* Tag subsequent instructions with the same location. */ - if (INSN_P (insn)) + if (NONDEBUG_INSN_P (insn)) INSN_LOCATOR (insn) = vliw_insn_location; } } @@ -3160,7 +3160,7 @@ picochip_reset_vliw (rtx insn) local_insn = insn; do { - if (NOTE_P (local_insn)) + if (NOTE_P (local_insn) || DEBUG_INSN_P(local_insn)) { local_insn = NEXT_INSN (local_insn); continue; @@ -3599,7 +3599,7 @@ picochip_final_prescan_insn (rtx insn, rtx * opvec ATTRIBUTE_UNUSED, for (local_insn = NEXT_INSN (local_insn); local_insn; local_insn = NEXT_INSN (local_insn)) { - if (NOTE_P (local_insn)) + if (NOTE_P (local_insn) || DEBUG_INSN_P(local_insn)) continue; else if (!INSN_P (local_insn)) break; @@ -3611,7 +3611,7 @@ picochip_final_prescan_insn (rtx insn, rtx * opvec ATTRIBUTE_UNUSED, /* Set the continuation flag if the next instruction can be packed with the current instruction (i.e., the next instruction is valid, and isn't the start of a new cycle). */ - picochip_vliw_continuation = (local_insn && INSN_P (local_insn) && + picochip_vliw_continuation = (local_insn && NONDEBUG_INSN_P (local_insn) && (GET_MODE (local_insn) != TImode)); } diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index d837d44c9be..6152e3655ec 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -743,14 +743,18 @@ extern unsigned rs6000_pointer_size; /* Make arrays of chars word-aligned for the same reasons. Align vectors to 128 bits. Align SPE vectors and E500 v2 doubles to 64 bits. */ -#define DATA_ALIGNMENT(TYPE, ALIGN) \ - (TREE_CODE (TYPE) == VECTOR_TYPE ? ((TARGET_SPE_ABI \ - || TARGET_PAIRED_FLOAT) ? 64 : 128) \ - : (TARGET_E500_DOUBLE \ - && TYPE_MODE (TYPE) == DFmode) ? 64 \ - : TREE_CODE (TYPE) == ARRAY_TYPE \ - && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ - && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) +#define DATA_ALIGNMENT(TYPE, ALIGN) \ + (TREE_CODE (TYPE) == VECTOR_TYPE \ + ? (((TARGET_SPE && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) \ + || (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) \ + ? 64 : 128) \ + : ((TARGET_E500_DOUBLE \ + && TREE_CODE (TYPE) == REAL_TYPE \ + && TYPE_MODE (TYPE) == DFmode) \ + ? 64 \ + : (TREE_CODE (TYPE) == ARRAY_TYPE \ + && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ + && (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN))) /* Nonzero if move instructions will actually fail to work when given unaligned data. */ diff --git a/gcc/config/rs6000/xcoff.h b/gcc/config/rs6000/xcoff.h index 6560f319a25..e5c47822355 100644 --- a/gcc/config/rs6000/xcoff.h +++ b/gcc/config/rs6000/xcoff.h @@ -190,7 +190,7 @@ putc ('.', FILE); \ RS6000_OUTPUT_BASENAME (FILE, buffer); \ fputs (":\n", FILE); \ - if (write_symbols != NO_DEBUG) \ + if (write_symbols != NO_DEBUG && !DECL_IGNORED_P (DECL)) \ xcoffout_declare_function (FILE, DECL, buffer); \ } diff --git a/gcc/config/sol2-c.c b/gcc/config/sol2-c.c index fc527b1beb7..da00377a432 100644 --- a/gcc/config/sol2-c.c +++ b/gcc/config/sol2-c.c @@ -36,8 +36,8 @@ along with GCC; see the file COPYING3. If not see /* cmn_err only accepts "l" and "ll". */ static const format_length_info cmn_err_length_specs[] = { - { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89 }, - { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89 } + { "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 }, + { NULL, FMT_LEN_none, STD_C89, NULL, FMT_LEN_none, STD_C89, 0 } }; static const format_flag_spec cmn_err_flag_specs[] = diff --git a/gcc/configure b/gcc/configure index 54cacad70c9..9ea03b2a624 100755 --- a/gcc/configure +++ b/gcc/configure @@ -24394,7 +24394,7 @@ else # simply assert that glibc does provide this, which is true for all # realistically usable GNU/Hurd configurations. gcc_cv_libc_provides_ssp=yes;; - *-*-darwin*) + *-*-darwin* | *-*-freebsd*) ac_fn_c_check_func "$LINENO" "__stack_chk_fail" "ac_cv_func___stack_chk_fail" if test "x$ac_cv_func___stack_chk_fail" = x""yes; then : gcc_cv_libc_provides_ssp=yes diff --git a/gcc/configure.ac b/gcc/configure.ac index 9cf2e0eba5b..383835e6fa0 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -3720,7 +3720,7 @@ AC_CACHE_CHECK(__stack_chk_fail in target C library, # simply assert that glibc does provide this, which is true for all # realistically usable GNU/Hurd configurations. gcc_cv_libc_provides_ssp=yes;; - *-*-darwin*) + *-*-darwin* | *-*-freebsd*) AC_CHECK_FUNC(__stack_chk_fail,[gcc_cv_libc_provides_ssp=yes], [echo "no __stack_chk_fail on this target"]) ;; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index db2a892988f..a50e9fcaf25 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,28 @@ +2009-09-13 Richard Guenther <rguenther@suse.de> + Rafael Avila de Espindola <espindola@google.com> + + * except.c (init_exception_processing): Do not set + lang_eh_runtime_type. + (choose_personality_routine): Do not set eh_personality_decl, + set pragma_java_exceptions. + * cp-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define. + (LANG_HOOKS_EH_PERSONALITY): Likewise. + (cp_eh_personality_decl): New. + (cp_eh_personality): Likewise. + * Make-lang.in (cp-lang.o): Add $(EXPR_H) and $(EXCEPT_H) + dependencies. + +2009-09-13 Wei Guozhi <carrot@google.com> + + PR c++/3187 + * cp/optimize.c (build_delete_destructor_body): New function. + (maybe_clone_body): Call build_delete_destructor_body for + deleting destructor. + +2009-09-10 Jason Merrill <jason@redhat.com> + + * repo.c (extract_string, get_base_filename, init_repo): constify. + 2009-09-09 Jason Merrill <jason@redhat.com> * error.c (find_typenames_r): Also add decltypes. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index da5d8ac2b18..861c93df066 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -250,7 +250,7 @@ cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ $(C_PRAGMA_H) toplev.h output.h input.h cp/operators.def $(TM_P_H) cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h debug.h langhooks.h \ $(LANGHOOKS_DEF_H) $(C_COMMON_H) gtype-cp.h \ - $(DIAGNOSTIC_H) cp/cp-objcp-common.h + $(DIAGNOSTIC_H) cp/cp-objcp-common.h $(EXPR_H) $(EXCEPT_H) cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/decl.h \ output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \ cp/operators.def $(TM_P_H) $(TREE_INLINE_H) $(DIAGNOSTIC_H) $(C_PRAGMA_H) \ diff --git a/gcc/cp/cp-lang.c b/gcc/cp/cp-lang.c index f818e5bb060..9521eab28cd 100644 --- a/gcc/cp/cp-lang.c +++ b/gcc/cp/cp-lang.c @@ -32,11 +32,14 @@ along with GCC; see the file COPYING3. If not see #include "debug.h" #include "cp-objcp-common.h" #include "hashtab.h" +#include "except.h" +#include "expr.h" enum c_language_kind c_language = clk_cxx; static void cp_init_ts (void); static const char * cxx_dwarf_name (tree t, int verbosity); static enum classify_record cp_classify_record (tree type); +static tree cp_eh_personality (void); /* Lang hooks common to C++ and ObjC++ are declared in cp/cp-objcp-common.h; consequently, there should be very few hooks below. */ @@ -71,6 +74,10 @@ static enum classify_record cp_classify_record (tree type); #define LANG_HOOKS_FOLD_OBJ_TYPE_REF cp_fold_obj_type_ref #undef LANG_HOOKS_INIT_TS #define LANG_HOOKS_INIT_TS cp_init_ts +#undef LANG_HOOKS_EH_PERSONALITY +#define LANG_HOOKS_EH_PERSONALITY cp_eh_personality +#undef LANG_HOOKS_EH_RUNTIME_TYPE +#define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type /* Each front end provides its own lang hook initializer. */ struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; @@ -145,4 +152,26 @@ finish_file (void) { } +static GTY(()) tree cp_eh_personality_decl; + +static tree +cp_eh_personality (void) +{ + if (!cp_eh_personality_decl) + { + if (!pragma_java_exceptions) + cp_eh_personality_decl + = build_personality_function (USING_SJLJ_EXCEPTIONS + ? "__gxx_personality_sj0" + : "__gxx_personality_v0"); + else + cp_eh_personality_decl + = build_personality_function (USING_SJLJ_EXCEPTIONS + ? "__gcj_personality_sj0" + : "__gcj_personality_v0"); + } + + return cp_eh_personality_decl; +} + #include "gtype-cp.h" diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ea3b4bf3d14..c720a565e7c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4521,6 +4521,7 @@ extern void choose_personality_routine (enum languages); extern tree eh_type_info (tree); extern tree begin_eh_spec_block (void); extern void finish_eh_spec_block (tree, tree); +extern tree build_eh_type_type (tree); /* in expr.c */ extern tree cplus_expand_constant (tree); diff --git a/gcc/cp/except.c b/gcc/cp/except.c index fdef154f5d1..588c2ee68d8 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -43,7 +43,6 @@ along with GCC; see the file COPYING3. If not see static void push_eh_cleanup (tree); static tree prepare_eh_type (tree); -static tree build_eh_type_type (tree); static tree do_begin_catch (void); static int dtor_nothrow (tree); static tree do_end_catch (tree); @@ -78,15 +77,11 @@ init_exception_processing (void) call_unexpected_node = push_throw_library_fn (get_identifier ("__cxa_call_unexpected"), tmp); - eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS - ? "__gxx_personality_sj0" - : "__gxx_personality_v0"); if (targetm.arm_eabi_unwinder) unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup"); else default_init_unwind_resume_libfunc (); - lang_eh_runtime_type = build_eh_type_type; lang_protect_cleanup_actions = &cp_protect_cleanup_actions; } @@ -143,7 +138,7 @@ eh_type_info (tree type) /* Build the address of a typeinfo decl for use in the runtime matching field of the exception model. */ -static tree +tree build_eh_type_type (tree type) { tree exp = eh_type_info (type); @@ -313,7 +308,7 @@ decl_is_java_type (tree decl, int err) /* Select the personality routine to be used for exception handling, or issue an error if we need two different ones in the same translation unit. - ??? At present eh_personality_libfunc is set to + ??? At present eh_personality_decl is set to __gxx_personality_(sj|v)0 in init_exception_processing - should it be done here instead? */ void @@ -354,9 +349,7 @@ choose_personality_routine (enum languages lang) case lang_java: state = chose_java; terminate_node = built_in_decls [BUILT_IN_ABORT]; - eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS - ? "__gcj_personality_sj0" - : "__gcj_personality_v0"); + pragma_java_exceptions = true; break; default: diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index c9d6cebb817..abd38f8666c 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -1,5 +1,5 @@ /* Perform optimizations on tree structure. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008 + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc. Written by Mark Michell (mark@codesourcery.com). @@ -106,6 +106,41 @@ clone_body (tree clone, tree fn, void *arg_map) append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone)); } +/* DELETE_DTOR is a delete destructor whose body will be built. + COMPLETE_DTOR is the corresponding complete destructor. */ + +static void +build_delete_destructor_body (tree delete_dtor, tree complete_dtor) +{ + tree call_dtor, call_delete; + tree parm = DECL_ARGUMENTS (delete_dtor); + tree virtual_size = cxx_sizeof (current_class_type); + + /* Call the corresponding complete destructor. */ + gcc_assert (complete_dtor); + call_dtor = build_cxx_call (complete_dtor, 1, &parm); + add_stmt (call_dtor); + + add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label)); + + /* Call the delete function. */ + call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr, + virtual_size, + /*global_p=*/false, + /*placement=*/NULL_TREE, + /*alloc_fn=*/NULL_TREE); + add_stmt (call_delete); + + /* Return the address of the object. */ + if (targetm.cxx.cdtor_returns_this ()) + { + tree val = DECL_ARGUMENTS (delete_dtor); + val = build2 (MODIFY_EXPR, TREE_TYPE (val), + DECL_RESULT (delete_dtor), val); + add_stmt (build_stmt (0, RETURN_EXPR, val)); + } +} + /* FN is a function that has a complete body. Clone the body as necessary. Returns nonzero if there's no longer any need to process the main body. */ @@ -114,6 +149,7 @@ bool maybe_clone_body (tree fn) { tree clone; + tree complete_dtor = NULL_TREE; bool first = true; /* We only clone constructors and destructors. */ @@ -124,6 +160,15 @@ maybe_clone_body (tree fn) /* Emit the DWARF1 abstract instance. */ (*debug_hooks->deferred_inline_function) (fn); + /* Look for the complete destructor which may be used to build the + delete destructor. */ + FOR_EACH_CLONE (clone, fn) + if (DECL_NAME (clone) == complete_dtor_identifier) + { + complete_dtor = clone; + break; + } + /* We know that any clones immediately follow FN in the TYPE_METHODS list. */ push_to_top_level (); @@ -176,59 +221,67 @@ maybe_clone_body (tree fn) /* Start processing the function. */ start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED); - /* Remap the parameters. */ - decl_map = pointer_map_create (); - for (parmno = 0, - parm = DECL_ARGUMENTS (fn), - clone_parm = DECL_ARGUMENTS (clone); - parm; - ++parmno, - parm = TREE_CHAIN (parm)) - { - /* Map the in-charge parameter to an appropriate constant. */ - if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1) - { - tree in_charge; - in_charge = in_charge_arg_for_name (DECL_NAME (clone)); - *pointer_map_insert (decl_map, parm) = in_charge; - } - else if (DECL_ARTIFICIAL (parm) - && DECL_NAME (parm) == vtt_parm_identifier) - { - /* For a subobject constructor or destructor, the next - argument is the VTT parameter. Remap the VTT_PARM - from the CLONE to this parameter. */ - if (DECL_HAS_VTT_PARM_P (clone)) - { - DECL_ABSTRACT_ORIGIN (clone_parm) = parm; - *pointer_map_insert (decl_map, parm) = clone_parm; - clone_parm = TREE_CHAIN (clone_parm); - } - /* Otherwise, map the VTT parameter to `NULL'. */ - else - *pointer_map_insert (decl_map, parm) - = fold_convert (TREE_TYPE (parm), null_pointer_node); - } - /* Map other parameters to their equivalents in the cloned - function. */ - else - { - *pointer_map_insert (decl_map, parm) = clone_parm; - clone_parm = TREE_CHAIN (clone_parm); - } - } - - if (targetm.cxx.cdtor_returns_this ()) - { - parm = DECL_RESULT (fn); - clone_parm = DECL_RESULT (clone); - *pointer_map_insert (decl_map, parm) = clone_parm; - } - /* Clone the body. */ - clone_body (clone, fn, decl_map); - - /* Clean up. */ - pointer_map_destroy (decl_map); + /* Build the delete destructor by calling complete destructor + and delete function. */ + if (DECL_NAME (clone) == deleting_dtor_identifier) + build_delete_destructor_body (clone, complete_dtor); + else + { + /* Remap the parameters. */ + decl_map = pointer_map_create (); + for (parmno = 0, + parm = DECL_ARGUMENTS (fn), + clone_parm = DECL_ARGUMENTS (clone); + parm; + ++parmno, + parm = TREE_CHAIN (parm)) + { + /* Map the in-charge parameter to an appropriate constant. */ + if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1) + { + tree in_charge; + in_charge = in_charge_arg_for_name (DECL_NAME (clone)); + *pointer_map_insert (decl_map, parm) = in_charge; + } + else if (DECL_ARTIFICIAL (parm) + && DECL_NAME (parm) == vtt_parm_identifier) + { + /* For a subobject constructor or destructor, the next + argument is the VTT parameter. Remap the VTT_PARM + from the CLONE to this parameter. */ + if (DECL_HAS_VTT_PARM_P (clone)) + { + DECL_ABSTRACT_ORIGIN (clone_parm) = parm; + *pointer_map_insert (decl_map, parm) = clone_parm; + clone_parm = TREE_CHAIN (clone_parm); + } + /* Otherwise, map the VTT parameter to `NULL'. */ + else + *pointer_map_insert (decl_map, parm) + = fold_convert (TREE_TYPE (parm), null_pointer_node); + } + /* Map other parameters to their equivalents in the cloned + function. */ + else + { + *pointer_map_insert (decl_map, parm) = clone_parm; + clone_parm = TREE_CHAIN (clone_parm); + } + } + + if (targetm.cxx.cdtor_returns_this ()) + { + parm = DECL_RESULT (fn); + clone_parm = DECL_RESULT (clone); + *pointer_map_insert (decl_map, parm) = clone_parm; + } + + /* Clone the body. */ + clone_body (clone, fn, decl_map); + + /* Clean up. */ + pointer_map_destroy (decl_map); + } /* The clone can throw iff the original function can throw. */ cp_function_chain->can_throw = !TREE_NOTHROW (fn); diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c index 0f531e2627c..aa970785ca3 100644 --- a/gcc/cp/repo.c +++ b/gcc/cp/repo.c @@ -37,7 +37,7 @@ along with GCC; see the file COPYING3. If not see #include "diagnostic.h" #include "flags.h" -static char *extract_string (char **); +static const char *extract_string (const char **); static const char *get_base_filename (const char *); static FILE *open_repo_file (const char *); static char *afgets (FILE *); @@ -53,10 +53,10 @@ static bool temporary_obstack_initialized_p; /* Parse a reasonable subset of shell quoting syntax. */ -static char * -extract_string (char **pp) +static const char * +extract_string (const char **pp) { - char *p = *pp; + const char *p = *pp; int backquote = 0; int inside = 0; @@ -89,13 +89,13 @@ extract_string (char **pp) static const char * get_base_filename (const char *filename) { - char *p = getenv ("COLLECT_GCC_OPTIONS"); + const char *p = getenv ("COLLECT_GCC_OPTIONS"); const char *output = NULL; int compiling = 0; while (p && *p) { - char *q = extract_string (&p); + const char *q = extract_string (&p); if (strcmp (q, "-o") == 0) { @@ -161,6 +161,7 @@ void init_repo (void) { char *buf; + const char *p; FILE *repo_file; if (! flag_use_repository) @@ -212,8 +213,8 @@ init_repo (void) fclose (repo_file); if (old_args && !get_random_seed (true) - && (buf = strstr (old_args, "'-frandom-seed="))) - set_random_seed (extract_string (&buf) + strlen ("-frandom-seed=")); + && (p = strstr (old_args, "'-frandom-seed="))) + set_random_seed (extract_string (&p) + strlen ("-frandom-seed=")); } static FILE * diff --git a/gcc/cselib.c b/gcc/cselib.c index 927f93cbb79..e6e5c143dad 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -1053,7 +1053,10 @@ cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth) } /* Same as cselib_expand_value_rtx, but using a callback to try to - resolve VALUEs that expand to nothing. */ + resolve some expressions. The CB function should return ORIG if it + can't or does not want to deal with a certain RTX. Any other + return value, including NULL, will be used as the expansion for + VALUE, without any further changes. */ rtx cselib_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth, @@ -1068,6 +1071,9 @@ cselib_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth, return cselib_expand_value_rtx_1 (orig, &evd, max_depth); } +/* Internal implementation of cselib_expand_value_rtx and + cselib_expand_value_rtx_cb. */ + static rtx cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd, int max_depth) @@ -1158,26 +1164,36 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd, case SUBREG: { - rtx subreg = cselib_expand_value_rtx_1 (SUBREG_REG (orig), evd, - max_depth - 1); + rtx subreg; + + if (evd->callback) + { + subreg = evd->callback (orig, evd->regs_active, max_depth, + evd->callback_arg); + if (subreg != orig) + return subreg; + } + + subreg = cselib_expand_value_rtx_1 (SUBREG_REG (orig), evd, + max_depth - 1); if (!subreg) return NULL; scopy = simplify_gen_subreg (GET_MODE (orig), subreg, GET_MODE (SUBREG_REG (orig)), SUBREG_BYTE (orig)); - if ((scopy == NULL - || (GET_CODE (scopy) == SUBREG - && !REG_P (SUBREG_REG (scopy)) - && !MEM_P (SUBREG_REG (scopy)))) - && (REG_P (SUBREG_REG (orig)) - || MEM_P (SUBREG_REG (orig)))) - return shallow_copy_rtx (orig); + if (scopy == NULL + || (GET_CODE (scopy) == SUBREG + && !REG_P (SUBREG_REG (scopy)) + && !MEM_P (SUBREG_REG (scopy)))) + return NULL; + return scopy; } case VALUE: { rtx result; + if (dump_file && (dump_flags & TDF_DETAILS)) { fputs ("\nexpanding ", dump_file); @@ -1185,20 +1201,16 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd, fputs (" into...", dump_file); } - if (!evd->callback) - result = NULL; - else + if (evd->callback) { result = evd->callback (orig, evd->regs_active, max_depth, evd->callback_arg); - if (result == orig) - result = NULL; - else if (result) - result = cselib_expand_value_rtx_1 (result, evd, max_depth); + + if (result != orig) + return result; } - if (!result) - result = expand_loc (CSELIB_VAL_PTR (orig)->locs, evd, max_depth); + result = expand_loc (CSELIB_VAL_PTR (orig)->locs, evd, max_depth); return result; } default: diff --git a/gcc/dbgcnt.c b/gcc/dbgcnt.c index 0c496b308d6..3fe34854f06 100644 --- a/gcc/dbgcnt.c +++ b/gcc/dbgcnt.c @@ -101,7 +101,7 @@ dbg_cnt_set_limit_by_name (const char *name, int len, int value) static const char * dbg_cnt_process_single_pair (const char *arg) { - char *colon = strchr (arg, ':'); + const char *colon = strchr (arg, ':'); char *endptr = NULL; int value; diff --git a/gcc/dbxout.c b/gcc/dbxout.c index bc7965e25b8..097b20be860 100644 --- a/gcc/dbxout.c +++ b/gcc/dbxout.c @@ -902,7 +902,7 @@ dbxout_finish_complex_stabs (tree sym, stab_code_type code, #if defined (DBX_DEBUGGING_INFO) static void -dbxout_function_end (tree decl) +dbxout_function_end (tree decl ATTRIBUTE_UNUSED) { char lscope_label_name[100]; @@ -921,8 +921,7 @@ dbxout_function_end (tree decl) named sections. */ if (!use_gnu_debug_info_extensions || NO_DBX_FUNCTION_END - || !targetm.have_named_sections - || DECL_IGNORED_P (decl)) + || !targetm.have_named_sections) return; /* By convention, GCC will mark the end of a function with an N_FUN @@ -3683,9 +3682,6 @@ dbxout_begin_function (tree decl) { int saved_tree_used1; - if (DECL_IGNORED_P (decl)) - return; - saved_tree_used1 = TREE_USED (decl); TREE_USED (decl) = 1; if (DECL_NAME (DECL_RESULT (decl)) != 0) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 4e9f18924d1..92f26e51970 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -2564,6 +2564,13 @@ SRAM@. The function will be put into a specific section named @code{.l1.text}. With @option{-mfdpic}, function calls with a such function as the callee or caller will use inlined PLT. +@item l2 +@cindex @code{l2} function attribute +On the Blackfin, this attribute specifies a function to be placed into L2 +SRAM. The function will be put into a specific section named +@code{.l1.text}. With @option{-mfdpic}, callers of such functions will use +an inlined PLT. + @item long_call/short_call @cindex indirect calls on ARM This attribute specifies how a particular function is called on @@ -4191,6 +4198,12 @@ Variables with @code{l1_data} attribute will be put into the specific section named @code{.l1.data}. Those with @code{l1_data_A} attribute will be put into the specific section named @code{.l1.data.A}. Those with @code{l1_data_B} attribute will be put into the specific section named @code{.l1.data.B}. + +@item l2 +@cindex @code{l2} variable attribute +Use this attribute on the Blackfin to place the variable into L2 SRAM. +Variables with @code{l2} attribute will be put into the specific section +named @code{.l2.data}. @end table @subsection M32R/D Variable Attributes diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index e0098bc156a..a929cca24fd 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -2710,7 +2710,7 @@ AIX: @uref{http://pware.hvcc.edu,,Hudson Valley Community College Open Source Software for IBM System p}; @item -@uref{http://www.perzl.org/aix,,AIX 5L and 6 Open Source Packages}. +@uref{http://www.perzl.org/aix/,,AIX 5L and 6 Open Source Packages}. @end itemize @item @@ -3070,8 +3070,6 @@ can also be obtained from: @item @uref{http://www.nongnu.org/avr/,,http://www.nongnu.org/avr/} @item -@uref{http://home.overta.ru/users/denisc/,,http://home.overta.ru/users/denisc/} -@item @uref{http://www.amelek.gda.pl/avr/,,http://www.amelek.gda.pl/avr/} @end itemize diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 1f9244abf01..986dd2d987d 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -6874,7 +6874,7 @@ Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}. @item -fstrict-aliasing @opindex fstrict-aliasing -Allows the compiler to assume the strictest aliasing rules applicable to +Allow the compiler to assume the strictest aliasing rules applicable to the language being compiled. For C (and C++), this activates optimizations based on the type of expressions. In particular, an object of one type is assumed never to reside at the same address as an @@ -6891,7 +6891,7 @@ union a_union @{ @}; int f() @{ - a_union t; + union a_union t; t.d = 3.0; return t.i; @} @@ -6904,7 +6904,7 @@ expected. @xref{Structures unions enumerations and bit-fields implementation}. However, this code might not: @smallexample int f() @{ - a_union t; + union a_union t; int* ip; t.d = 3.0; ip = &t.i; diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 62459e237f3..6f0b965d2e7 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -216,6 +216,10 @@ static GTY(()) section *debug_str_section; static GTY(()) section *debug_ranges_section; static GTY(()) section *debug_frame_section; +/* Personality decl of current unit. Used only when assembler does not support + personality CFI. */ +static GTY(()) rtx current_unit_personality; + /* How to start an assembler comment. */ #ifndef ASM_COMMENT_START #define ASM_COMMENT_START ";#" @@ -3599,6 +3603,7 @@ output_call_frame_info (int for_eh) int per_encoding = DW_EH_PE_absptr; int lsda_encoding = DW_EH_PE_absptr; int return_reg; + rtx personality = NULL; int dw_cie_version; /* Don't emit a CIE if there won't be any FDEs. */ @@ -3684,6 +3689,8 @@ output_call_frame_info (int for_eh) augmentation[0] = 0; augmentation_size = 0; + + personality = current_unit_personality; if (for_eh) { char *p; @@ -3703,11 +3710,11 @@ output_call_frame_info (int for_eh) lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0); p = augmentation + 1; - if (eh_personality_libfunc) + if (personality) { *p++ = 'P'; augmentation_size += 1 + size_of_encoded_value (per_encoding); - assemble_external_libcall (eh_personality_libfunc); + assemble_external_libcall (personality); } if (any_lsda_needed) { @@ -3726,7 +3733,7 @@ output_call_frame_info (int for_eh) } /* Ug. Some platforms can't do unaligned dynamic relocations at all. */ - if (eh_personality_libfunc && per_encoding == DW_EH_PE_aligned) + if (personality && per_encoding == DW_EH_PE_aligned) { int offset = ( 4 /* Length */ + 4 /* CIE Id */ @@ -3760,12 +3767,12 @@ output_call_frame_info (int for_eh) if (augmentation[0]) { dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size"); - if (eh_personality_libfunc) + if (personality) { dw2_asm_output_data (1, per_encoding, "Personality (%s)", eh_data_format_name (per_encoding)); dw2_asm_output_encoded_addr_rtx (per_encoding, - eh_personality_libfunc, + personality, true, NULL); } @@ -3824,13 +3831,14 @@ dwarf2out_do_cfi_startproc (bool second) { int enc; rtx ref; + rtx personality = get_personality_function (current_function_decl); fprintf (asm_out_file, "\t.cfi_startproc\n"); - if (eh_personality_libfunc) + if (personality) { enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1); - ref = eh_personality_libfunc; + ref = personality; /* ??? The GAS support isn't entirely consistent. We have to handle indirect support ourselves, but PC-relative is done @@ -3873,6 +3881,7 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, char label[MAX_ARTIFICIAL_LABEL_BYTES]; char * dup_label; dw_fde_ref fde; + rtx personality; section *fnsec; current_function_func_begin_label = NULL; @@ -3967,8 +3976,17 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, dwarf2out_source_line (line, file, 0, true); #endif + personality = get_personality_function (current_function_decl); if (dwarf2out_do_cfi_asm ()) dwarf2out_do_cfi_startproc (false); + else + { + if (!current_unit_personality || current_unit_personality == personality) + current_unit_personality = personality; + else + sorry ("Multiple EH personalities are supported only with assemblers " + "supporting .cfi.personality directive."); + } } /* Output a marker (i.e. a label) for the absolute end of the generated code diff --git a/gcc/except.c b/gcc/except.c index c97928eadf1..9b6c24eff9b 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -92,9 +92,6 @@ gimple (*lang_protect_cleanup_actions) (void); /* Return true if type A catches type B. */ int (*lang_eh_type_covers) (tree a, tree b); -/* Map a type to a runtime object to match type. */ -tree (*lang_eh_runtime_type) (tree); - /* A hash table of label to region number. */ struct GTY(()) ehl_map_entry { @@ -1696,7 +1693,7 @@ add_type_for_runtime (tree type) TREE_HASH (type), INSERT); if (*slot == NULL) { - tree runtime = (*lang_eh_runtime_type) (type); + tree runtime = lang_hooks.eh_runtime_type (type); *slot = tree_cons (type, runtime, NULL_TREE); } } @@ -2424,6 +2421,7 @@ sjlj_emit_function_enter (rtx dispatch_label) { rtx fn_begin, fc, mem, seq; bool fn_begin_outside_block; + rtx personality = get_personality_function (current_function_decl); fc = crtl->eh.sjlj_fc; @@ -2432,9 +2430,9 @@ sjlj_emit_function_enter (rtx dispatch_label) /* We're storing this libcall's address into memory instead of calling it directly. Thus, we must call assemble_external_libcall here, as we can not depend on emit_library_call to do it for us. */ - assemble_external_libcall (eh_personality_libfunc); + assemble_external_libcall (personality); mem = adjust_address (fc, Pmode, sjlj_fc_personality_ofs); - emit_move_insn (mem, eh_personality_libfunc); + emit_move_insn (mem, personality); mem = adjust_address (fc, Pmode, sjlj_fc_lsda_ofs); if (crtl->uses_eh_lsda) @@ -4394,7 +4392,7 @@ output_ttype (tree type, int tt_format, int tt_format_size) static void output_one_function_exception_table (const char * ARG_UNUSED (fnname), - int section) + int section, rtx ARG_UNUSED (personality)) { int tt_format, cs_format, lp_format, i, n; #ifdef HAVE_AS_LEB128 @@ -4410,7 +4408,7 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname), #ifdef TARGET_UNWIND_INFO /* TODO: Move this into target file. */ fputs ("\t.personality\t", asm_out_file); - output_addr_const (asm_out_file, eh_personality_libfunc); + output_addr_const (asm_out_file, personality); fputs ("\n\t.handlerdata\n", asm_out_file); /* Note that varasm still thinks we're in the function's code section. The ".endp" directive that will immediately follow will take us back. */ @@ -4580,16 +4578,18 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname), void output_function_exception_table (const char * ARG_UNUSED (fnname)) { + rtx personality = get_personality_function (current_function_decl); + /* Not all functions need anything. */ if (! crtl->uses_eh_lsda) return; - if (eh_personality_libfunc) - assemble_external_libcall (eh_personality_libfunc); + if (personality) + assemble_external_libcall (personality); - output_one_function_exception_table (fnname, 0); + output_one_function_exception_table (fnname, 0, personality); if (crtl->eh.call_site_record[1] != NULL) - output_one_function_exception_table (fnname, 1); + output_one_function_exception_table (fnname, 1, personality); switch_to_section (current_function_section ()); } @@ -4606,6 +4606,70 @@ get_eh_throw_stmt_table (struct function *fun) return fun->eh->throw_stmt_table; } +/* Return true if the function deeds a EH personality function. */ + +enum eh_personality_kind +function_needs_eh_personality (struct function *fn) +{ + struct eh_region_d *i; + int depth = 0; + enum eh_personality_kind kind = eh_personality_none; + + i = fn->eh->region_tree; + if (!i) + return eh_personality_none; + + while (1) + { + switch (i->type) + { + case ERT_TRY: + case ERT_THROW: + /* Do not need a EH personality function. */ + break; + + case ERT_MUST_NOT_THROW: + /* Always needs a EH personality function. */ + return eh_personality_lang; + + case ERT_CLEANUP: + /* Can do with any personality including the generic C one. */ + kind = eh_personality_any; + break; + + case ERT_CATCH: + case ERT_ALLOWED_EXCEPTIONS: + /* Always needs a EH personality function. The generic C + personality doesn't handle these even for empty type lists. */ + return eh_personality_lang; + + case ERT_UNKNOWN: + return eh_personality_lang; + } + /* If there are sub-regions, process them. */ + if (i->inner) + i = i->inner, depth++; + /* If there are peers, process them. */ + else if (i->next_peer) + i = i->next_peer; + /* Otherwise, step back up the tree to the next peer. */ + else + { + do + { + i = i->outer; + depth--; + if (i == NULL) + return kind; + } + while (i->next_peer == NULL); + i = i->next_peer; + } + } + + return kind; +} + /* Dump EH information to OUT. */ void diff --git a/gcc/except.h b/gcc/except.h index f332b2b1bb7..af63e983a3a 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -217,9 +217,6 @@ extern gimple (*lang_protect_cleanup_actions) (void); /* Return true if type A catches type B. */ extern int (*lang_eh_type_covers) (tree a, tree b); -/* Map a type to a runtime object to match type. */ -extern tree (*lang_eh_runtime_type) (tree); - /* Just because the user configured --with-sjlj-exceptions=no doesn't mean that we can use call frame exceptions. Detect that the target @@ -277,3 +274,12 @@ extern int num_eh_regions (void); extern bitmap must_not_throw_labels (void); extern struct eh_region_d *redirect_eh_edge_to_label (struct edge_def *, tree, bool, bool, int); extern int get_next_region_sharing_label (int); + +enum eh_personality_kind { + eh_personality_none, + eh_personality_any, + eh_personality_lang +}; + +extern enum eh_personality_kind +function_needs_eh_personality (struct function *); diff --git a/gcc/expr.c b/gcc/expr.c index fe74280d7fe..be3b5bb5e5b 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -761,6 +761,9 @@ convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int uns if (GET_MODE (x) != VOIDmode) oldmode = GET_MODE (x); + if (mode == oldmode) + return x; + /* There is one case that we must handle specially: If we are converting a CONST_INT into a mode whose size is twice HOST_BITS_PER_WIDE_INT and we are to interpret the constant as unsigned, gen_lowpart will do @@ -826,9 +829,6 @@ convert_modes (enum machine_mode mode, enum machine_mode oldmode, rtx x, int uns return gen_lowpart (mode, x); } - if (mode == oldmode) - return x; - /* Converting from integer constant into mode is always equivalent to an subreg operation. */ if (VECTOR_MODE_P (mode) && GET_MODE (x) == VOIDmode) @@ -10214,4 +10214,52 @@ const_vector_from_tree (tree exp) return gen_rtx_CONST_VECTOR (mode, v); } + + +/* Build a decl for a EH personality function named NAME. */ + +tree +build_personality_function (const char *name) +{ + tree decl, type; + + type = build_function_type_list (integer_type_node, integer_type_node, + long_long_unsigned_type_node, + ptr_type_node, ptr_type_node, NULL_TREE); + decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, + get_identifier (name), type); + DECL_ARTIFICIAL (decl) = 1; + DECL_EXTERNAL (decl) = 1; + TREE_PUBLIC (decl) = 1; + + /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with + are the flags assigned by targetm.encode_section_info. */ + SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL); + + return decl; +} + +/* Extracts the personality function of DECL and returns the corresponding + libfunc. */ + +rtx +get_personality_function (tree decl) +{ + tree personality = DECL_FUNCTION_PERSONALITY (decl); + enum eh_personality_kind pk; + + pk = function_needs_eh_personality (DECL_STRUCT_FUNCTION (decl)); + if (pk == eh_personality_none) + return NULL; + + if (!personality + && pk == eh_personality_any) + personality = lang_hooks.eh_personality (); + + if (pk == eh_personality_lang) + gcc_assert (personality != NULL_TREE); + + return XEXP (DECL_RTL (personality), 0); +} + #include "gt-expr.h" diff --git a/gcc/expr.h b/gcc/expr.h index 8eddb44be43..9bf0c38f5d2 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -814,6 +814,12 @@ extern void init_all_optabs (void); extern rtx init_one_libfunc (const char *); extern rtx set_user_assembler_libfunc (const char *, const char *); +/* Build a decl for a libfunc named NAME. */ +extern tree build_libfunc_function (const char *); + +/* Get the personality libfunc for a function decl. */ +rtx get_personality_function (tree); + extern int vector_mode_valid_p (enum machine_mode); #endif /* GCC_EXPR_H */ diff --git a/gcc/final.c b/gcc/final.c index 76c52ca100e..3ecb415d795 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1081,7 +1081,7 @@ shorten_branches (rtx first ATTRIBUTE_UNUSED) INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid]; if (NOTE_P (insn) || BARRIER_P (insn) - || LABEL_P (insn)) + || LABEL_P (insn) || DEBUG_INSN_P(insn)) continue; if (INSN_DELETED_P (insn)) continue; @@ -1484,6 +1484,20 @@ remap_debug_filename (const char *filename) return ggc_strdup (s); } +/* Return true if DWARF2 debug info can be emitted for DECL. */ + +static bool +dwarf2_debug_info_emitted_p (tree decl) +{ + if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG) + return false; + + if (DECL_IGNORED_P (decl)) + return false; + + return true; +} + /* Output assembler code for the start of a function, and initialize some of the variables in this file for the new function. The label for the function and associated @@ -1508,10 +1522,11 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file, high_block_linenum = high_function_linenum = last_linenum; - (*debug_hooks->begin_prologue) (last_linenum, last_filename); + if (!DECL_IGNORED_P (current_function_decl)) + debug_hooks->begin_prologue (last_linenum, last_filename); #if defined (DWARF2_UNWIND_INFO) || defined (TARGET_UNWIND_INFO) - if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG) + if (!dwarf2_debug_info_emitted_p (current_function_decl)) dwarf2out_begin_prologue (0, NULL); #endif @@ -1648,17 +1663,19 @@ final_end_function (void) { app_disable (); - (*debug_hooks->end_function) (high_function_linenum); + if (!DECL_IGNORED_P (current_function_decl)) + debug_hooks->end_function (high_function_linenum); /* Finally, output the function epilogue: code to restore the stack frame and return to the caller. */ targetm.asm_out.function_epilogue (asm_out_file, get_frame_size ()); /* And debug output. */ - (*debug_hooks->end_epilogue) (last_linenum, last_filename); + if (!DECL_IGNORED_P (current_function_decl)) + debug_hooks->end_epilogue (last_linenum, last_filename); #if defined (DWARF2_UNWIND_INFO) - if (write_symbols != DWARF2_DEBUG && write_symbols != VMS_AND_DWARF2_DEBUG + if (!dwarf2_debug_info_emitted_p (current_function_decl) && dwarf2out_do_frame ()) dwarf2out_end_epilogue (last_linenum, last_filename); #endif @@ -1839,7 +1856,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, dwarf2out_switch_text_section (); else #endif - (*debug_hooks->switch_text_section) (); + if (!DECL_IGNORED_P (current_function_decl)) + debug_hooks->switch_text_section (); switch_to_section (current_function_section ()); break; @@ -1905,7 +1923,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, case NOTE_INSN_FUNCTION_BEG: app_disable (); - (*debug_hooks->end_prologue) (last_linenum, last_filename); + if (!DECL_IGNORED_P (current_function_decl)) + debug_hooks->end_prologue (last_linenum, last_filename); if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE) { @@ -1931,7 +1950,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, high_block_linenum = last_linenum; /* Output debugging info about the symbol-block beginning. */ - (*debug_hooks->begin_block) (last_linenum, n); + if (!DECL_IGNORED_P (current_function_decl)) + debug_hooks->begin_block (last_linenum, n); /* Mark this block as output. */ TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1; @@ -1965,7 +1985,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, --block_depth; gcc_assert (block_depth >= 0); - (*debug_hooks->end_block) (high_block_linenum, n); + if (!DECL_IGNORED_P (current_function_decl)) + debug_hooks->end_block (high_block_linenum, n); } if (write_symbols == DBX_DEBUG || write_symbols == SDB_DEBUG) @@ -1995,7 +2016,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, break; case NOTE_INSN_VAR_LOCATION: - (*debug_hooks->var_location) (insn); + if (!DECL_IGNORED_P (current_function_decl)) + debug_hooks->var_location (insn); break; default: @@ -2038,8 +2060,8 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, CC_STATUS_INIT; #endif - if (LABEL_NAME (insn)) - (*debug_hooks->label) (insn); + if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn)) + debug_hooks->label (insn); app_disable (); @@ -2193,13 +2215,10 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED, } /* Output this line note if it is the first or the last line note in a row. */ - if (notice_source_line (insn, &is_stmt)) - { - (*debug_hooks->source_line) (last_linenum, - last_filename, - last_discriminator, - is_stmt); - } + if (!DECL_IGNORED_P (current_function_decl) + && notice_source_line (insn, &is_stmt)) + (*debug_hooks->source_line) (last_linenum, last_filename, + last_discriminator, is_stmt); if (GET_CODE (body) == ASM_INPUT) { @@ -4261,7 +4280,8 @@ rest_of_handle_final (void) *will* be routed past here. */ timevar_push (TV_SYMOUT); - (*debug_hooks->function_decl) (current_function_decl); + if (!DECL_IGNORED_P (current_function_decl)) + debug_hooks->function_decl (current_function_decl); timevar_pop (TV_SYMOUT); /* Release the blocks that are linked to DECL_INITIAL() to free the memory. */ diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index c01c4b351b0..7cf6e86d9b0 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,26 @@ +2009-09-13 Richard Guenther <rguenther@suse.de> + Rafael Avila de Espindola <espindola@google.com> + + * f95-lang.c (gfc_maybe_initialize_eh): Do not init + eh_personality_libfunc. + +2009-09-11 Janus Weil <janus@gcc.gnu.org> + + PR fortran/41242 + * resolve.c (resolve_ordinary_assign): Don't call resolve_code, + to avoid that subsequent codes are resolved more than once. + (resolve_code): Make sure that type-bound assignment operators are + resolved correctly. + + +2009-09-10 Steven G. Kargl <kargl@gcc.gnu.org> + + PR fortran/31292 + * fortran/decl.c(gfc_match_modproc): Check that module procedures + from a module can USEd in module procedure statements in other + program units. Update locus for better error message display. + Detect intrinsic procedures in module procedure statements. + 2009-09-09 Richard Guenther <rguenther@suse.de> PR fortran/41297 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index 52796a65575..3ce7fd4a337 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -6485,7 +6485,10 @@ gfc_match_modproc (void) module_ns = gfc_current_ns->parent; for (; module_ns; module_ns = module_ns->parent) - if (module_ns->proc_name->attr.flavor == FL_MODULE) + if (module_ns->proc_name->attr.flavor == FL_MODULE + || module_ns->proc_name->attr.flavor == FL_PROGRAM + || (module_ns->proc_name->attr.flavor == FL_PROCEDURE + && !module_ns->proc_name->attr.contained)) break; if (module_ns == NULL) @@ -6497,6 +6500,7 @@ gfc_match_modproc (void) for (;;) { + locus old_locus = gfc_current_locus; bool last = false; m = gfc_match_name (name); @@ -6517,6 +6521,13 @@ gfc_match_modproc (void) if (gfc_get_symbol (name, module_ns, &sym)) return MATCH_ERROR; + if (sym->attr.intrinsic) + { + gfc_error ("Intrinsic procedure at %L cannot be a MODULE " + "PROCEDURE", &old_locus); + return MATCH_ERROR; + } + if (sym->attr.proc != PROC_MODULE && gfc_add_procedure (&sym->attr, PROC_MODULE, sym->name, NULL) == FAILURE) @@ -6526,6 +6537,7 @@ gfc_match_modproc (void) return MATCH_ERROR; sym->attr.mod_proc = 1; + sym->declared_at = old_locus; if (last) break; diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c index e061538878f..3d94fd62424 100644 --- a/gcc/fortran/f95-lang.c +++ b/gcc/fortran/f95-lang.c @@ -1155,10 +1155,6 @@ gfc_maybe_initialize_eh (void) return; gfc_eh_initialized_p = true; - eh_personality_libfunc - = init_one_libfunc (USING_SJLJ_EXCEPTIONS - ? "__gcc_personality_sj0" - : "__gcc_personality_v0"); default_init_unwind_resume_libfunc (); using_eh_for_cleanups (); } diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index fd365eb136a..f208f406626 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -6958,7 +6958,6 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns) && (lhs->symtree->n.sym == (*rhsptr)->symtree->n.sym)) *rhsptr = gfc_get_parentheses (*rhsptr); - resolve_code (code, ns); return true; } @@ -7190,7 +7189,12 @@ resolve_code (gfc_code *code, gfc_namespace *ns) break; if (resolve_ordinary_assign (code, ns)) - goto call; + { + if (code->op == EXEC_COMPCALL) + goto compcall; + else + goto call; + } break; @@ -7241,6 +7245,7 @@ resolve_code (gfc_code *code, gfc_namespace *ns) break; case EXEC_COMPCALL: + compcall: resolve_typebound_call (code); break; diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c index 666b47b47a8..876225b8bf9 100644 --- a/gcc/gimple-iterator.c +++ b/gcc/gimple-iterator.c @@ -623,9 +623,9 @@ gimple_find_edge_insert_loc (edge e, gimple_stmt_iterator *gsi, would have to examine the PHIs to prove that none of them used the value set by the statement we want to insert on E. That hardly seems worth the effort. */ -restart: + restart: if (single_pred_p (dest) - && ! phi_nodes (dest) + && gimple_seq_empty_p (phi_nodes (dest)) && dest != EXIT_BLOCK_PTR) { *gsi = gsi_start_bb (dest); @@ -667,10 +667,13 @@ restart: if (!stmt_ends_bb_p (tmp)) return true; - if (gimple_code (tmp) == GIMPLE_RETURN) - { - gsi_prev (gsi); - return true; + switch (gimple_code (tmp)) + { + case GIMPLE_RETURN: + case GIMPLE_RESX: + return false; + default: + break; } } diff --git a/gcc/gimple.c b/gcc/gimple.c index 9223aaa8824..3be6d843fe2 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -35,18 +35,32 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "demangle.h" -#define DEFGSCODE(SYM, NAME, STRUCT) NAME, -const char *const gimple_code_name[] = { -#include "gimple.def" -}; -#undef DEFGSCODE -/* All the tuples have their operand vector at the very bottom +/* All the tuples have their operand vector (if present) at the very bottom of the structure. Therefore, the offset required to find the operands vector the size of the structure minus the size of the 1 element tree array at the end (see gimple_ops). */ -#define DEFGSCODE(SYM, NAME, STRUCT) (sizeof (STRUCT) - sizeof (tree)), +#define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) \ + (HAS_TREE_OP ? sizeof (struct STRUCT) - sizeof (tree) : 0), EXPORTED_CONST size_t gimple_ops_offset_[] = { +#include "gsstruct.def" +}; +#undef DEFGSSTRUCT + +#define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) sizeof(struct STRUCT), +static const size_t gsstruct_code_size[] = { +#include "gsstruct.def" +}; +#undef DEFGSSTRUCT + +#define DEFGSCODE(SYM, NAME, GSSCODE) NAME, +const char *const gimple_code_name[] = { +#include "gimple.def" +}; +#undef DEFGSCODE + +#define DEFGSCODE(SYM, NAME, GSSCODE) GSSCODE, +EXPORTED_CONST enum gimple_statement_structure_enum gss_for_code_[] = { #include "gimple.def" }; #undef DEFGSCODE @@ -89,118 +103,15 @@ gimple_set_code (gimple g, enum gimple_code code) g->gsbase.code = code; } - -/* Return the GSS_* identifier for the given GIMPLE statement CODE. */ - -static enum gimple_statement_structure_enum -gss_for_code (enum gimple_code code) -{ - switch (code) - { - case GIMPLE_ASSIGN: - case GIMPLE_CALL: - case GIMPLE_RETURN: return GSS_WITH_MEM_OPS; - case GIMPLE_COND: - case GIMPLE_GOTO: - case GIMPLE_LABEL: - case GIMPLE_DEBUG: - case GIMPLE_SWITCH: return GSS_WITH_OPS; - case GIMPLE_ASM: return GSS_ASM; - case GIMPLE_BIND: return GSS_BIND; - case GIMPLE_CATCH: return GSS_CATCH; - case GIMPLE_EH_FILTER: return GSS_EH_FILTER; - case GIMPLE_NOP: return GSS_BASE; - case GIMPLE_PHI: return GSS_PHI; - case GIMPLE_RESX: return GSS_RESX; - case GIMPLE_TRY: return GSS_TRY; - case GIMPLE_WITH_CLEANUP_EXPR: return GSS_WCE; - case GIMPLE_OMP_CRITICAL: return GSS_OMP_CRITICAL; - case GIMPLE_OMP_FOR: return GSS_OMP_FOR; - case GIMPLE_OMP_MASTER: - case GIMPLE_OMP_ORDERED: - case GIMPLE_OMP_SECTION: return GSS_OMP; - case GIMPLE_OMP_RETURN: - case GIMPLE_OMP_SECTIONS_SWITCH: return GSS_BASE; - case GIMPLE_OMP_CONTINUE: return GSS_OMP_CONTINUE; - case GIMPLE_OMP_PARALLEL: return GSS_OMP_PARALLEL; - case GIMPLE_OMP_TASK: return GSS_OMP_TASK; - case GIMPLE_OMP_SECTIONS: return GSS_OMP_SECTIONS; - case GIMPLE_OMP_SINGLE: return GSS_OMP_SINGLE; - case GIMPLE_OMP_ATOMIC_LOAD: return GSS_OMP_ATOMIC_LOAD; - case GIMPLE_OMP_ATOMIC_STORE: return GSS_OMP_ATOMIC_STORE; - case GIMPLE_PREDICT: return GSS_BASE; - default: gcc_unreachable (); - } -} - - /* Return the number of bytes needed to hold a GIMPLE statement with code CODE. */ -static size_t +static inline size_t gimple_size (enum gimple_code code) { - enum gimple_statement_structure_enum gss = gss_for_code (code); - - if (gss == GSS_WITH_OPS) - return sizeof (struct gimple_statement_with_ops); - else if (gss == GSS_WITH_MEM_OPS) - return sizeof (struct gimple_statement_with_memory_ops); - - switch (code) - { - case GIMPLE_ASM: - return sizeof (struct gimple_statement_asm); - case GIMPLE_NOP: - return sizeof (struct gimple_statement_base); - case GIMPLE_BIND: - return sizeof (struct gimple_statement_bind); - case GIMPLE_CATCH: - return sizeof (struct gimple_statement_catch); - case GIMPLE_EH_FILTER: - return sizeof (struct gimple_statement_eh_filter); - case GIMPLE_TRY: - return sizeof (struct gimple_statement_try); - case GIMPLE_RESX: - return sizeof (struct gimple_statement_resx); - case GIMPLE_OMP_CRITICAL: - return sizeof (struct gimple_statement_omp_critical); - case GIMPLE_OMP_FOR: - return sizeof (struct gimple_statement_omp_for); - case GIMPLE_OMP_PARALLEL: - return sizeof (struct gimple_statement_omp_parallel); - case GIMPLE_OMP_TASK: - return sizeof (struct gimple_statement_omp_task); - case GIMPLE_OMP_SECTION: - case GIMPLE_OMP_MASTER: - case GIMPLE_OMP_ORDERED: - return sizeof (struct gimple_statement_omp); - case GIMPLE_OMP_RETURN: - return sizeof (struct gimple_statement_base); - case GIMPLE_OMP_CONTINUE: - return sizeof (struct gimple_statement_omp_continue); - case GIMPLE_OMP_SECTIONS: - return sizeof (struct gimple_statement_omp_sections); - case GIMPLE_OMP_SECTIONS_SWITCH: - return sizeof (struct gimple_statement_base); - case GIMPLE_OMP_SINGLE: - return sizeof (struct gimple_statement_omp_single); - case GIMPLE_OMP_ATOMIC_LOAD: - return sizeof (struct gimple_statement_omp_atomic_load); - case GIMPLE_OMP_ATOMIC_STORE: - return sizeof (struct gimple_statement_omp_atomic_store); - case GIMPLE_WITH_CLEANUP_EXPR: - return sizeof (struct gimple_statement_wce); - case GIMPLE_PREDICT: - return sizeof (struct gimple_statement_base); - default: - break; - } - - gcc_unreachable (); + return gsstruct_code_size[gss_for_code (code)]; } - /* Allocate memory for a GIMPLE statement with code CODE and NUM_OPS operands. */ @@ -1103,15 +1014,6 @@ gimple_build_predict (enum br_predictor predictor, enum prediction outcome) return p; } -/* Return which gimple structure is used by T. The enums here are defined - in gsstruct.def. */ - -enum gimple_statement_structure_enum -gimple_statement_structure (gimple gs) -{ - return gss_for_code (gimple_code (gs)); -} - #if defined ENABLE_GIMPLE_CHECKING /* Complain of a gimple type mismatch and die. */ diff --git a/gcc/gimple.def b/gcc/gimple.def index 716f6e2acbb..1a3f345e106 100644 --- a/gcc/gimple.def +++ b/gcc/gimple.def @@ -20,19 +20,11 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ /* The format of this file is - DEFGSCODE(GIMPLE_symbol, printable name, structure). + DEFGSCODE(GIMPLE_symbol, printable name, GSS_symbol). */ - Where symbol is the enumeration name without the ``GIMPLE_''. - The argument STRUCTURE is used to compute offsets into each of the - tuple structures that contain operands. Since vector operands - are at different offsets depending on the particular structure - used, these offsets are computed at compile time for efficient - lookup at runtime. See gimple_ops(). - - If a code does not use operand vectors, STRUCTURE should be NULL. */ /* Error marker. This is used in similar ways as ERROR_MARK in tree.def. */ -DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", NULL) +DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", GSS_BASE) /* IMPORTANT. Do not rearrange the codes between GIMPLE_COND and GIMPLE_RETURN. The ordering is exposed by gimple_has_ops calls. @@ -51,18 +43,18 @@ DEFGSCODE(GIMPLE_ERROR_MARK, "gimple_error_mark", NULL) TRUE_LABEL and FALSE_LABEL are the LABEL_DECL nodes used as the jump target for the comparison. */ -DEFGSCODE(GIMPLE_COND, "gimple_cond", struct gimple_statement_with_ops) +DEFGSCODE(GIMPLE_COND, "gimple_cond", GSS_WITH_OPS) /* GIMPLE_DEBUG represents a debug statement. */ -DEFGSCODE(GIMPLE_DEBUG, "gimple_debug", struct gimple_statement_with_ops) +DEFGSCODE(GIMPLE_DEBUG, "gimple_debug", GSS_WITH_OPS) /* GIMPLE_GOTO <TARGET> represents unconditional jumps. TARGET is a LABEL_DECL or an expression node for computed GOTOs. */ -DEFGSCODE(GIMPLE_GOTO, "gimple_goto", struct gimple_statement_with_ops) +DEFGSCODE(GIMPLE_GOTO, "gimple_goto", GSS_WITH_OPS) /* GIMPLE_LABEL <LABEL> represents label statements. LABEL is a LABEL_DECL representing a jump target. */ -DEFGSCODE(GIMPLE_LABEL, "gimple_label", struct gimple_statement_with_ops) +DEFGSCODE(GIMPLE_LABEL, "gimple_label", GSS_WITH_OPS) /* GIMPLE_SWITCH <INDEX, DEFAULT_LAB, LAB1, ..., LABN> represents the multiway branch: @@ -79,7 +71,7 @@ DEFGSCODE(GIMPLE_LABEL, "gimple_label", struct gimple_statement_with_ops) DEFAULT_LAB, LAB1 ... LABN are the tree nodes representing case labels. They must be CASE_LABEL_EXPR nodes. */ -DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", struct gimple_statement_with_ops) +DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", GSS_WITH_OPS) /* IMPORTANT. @@ -106,8 +98,7 @@ DEFGSCODE(GIMPLE_SWITCH, "gimple_switch", struct gimple_statement_with_ops) RHS2 is the second operand on the RHS of the assignment. It must be a tree node accepted by is_gimple_val. This argument exists only if SUBCODE is of class GIMPLE_BINARY_RHS. */ -DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign", - struct gimple_statement_with_memory_ops) +DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign", GSS_WITH_MEM_OPS) /* GIMPLE_ASM <STRING, I1, ..., IN, O1, ... OM, C1, ..., CP> represents inline assembly statements. @@ -116,7 +107,7 @@ DEFGSCODE(GIMPLE_ASSIGN, "gimple_assign", I1 ... IN are the N input operands. O1 ... OM are the M output operands. C1 ... CP are the P clobber operands. */ -DEFGSCODE(GIMPLE_ASM, "gimple_asm", struct gimple_statement_asm) +DEFGSCODE(GIMPLE_ASM, "gimple_asm", GSS_ASM) /* GIMPLE_CALL <FN, LHS, ARG1, ..., ARGN[, CHAIN]> represents function calls. @@ -130,31 +121,29 @@ DEFGSCODE(GIMPLE_ASM, "gimple_asm", struct gimple_statement_asm) is_gimple_operand. CHAIN is the optional static chain link for nested functions. */ -DEFGSCODE(GIMPLE_CALL, "gimple_call", - struct gimple_statement_with_memory_ops) +DEFGSCODE(GIMPLE_CALL, "gimple_call", GSS_WITH_MEM_OPS) /* GIMPLE_RETURN <RETVAL> represents return statements. RETVAL is the value to return or NULL. If a value is returned it must be accepted by is_gimple_operand. */ -DEFGSCODE(GIMPLE_RETURN, "gimple_return", - struct gimple_statement_with_memory_ops) +DEFGSCODE(GIMPLE_RETURN, "gimple_return", GSS_WITH_MEM_OPS) /* GIMPLE_BIND <VARS, BLOCK, BODY> represents a lexical scope. VARS is the set of variables declared in that scope. BLOCK is the symbol binding block used for debug information. BODY is the sequence of statements in the scope. */ -DEFGSCODE(GIMPLE_BIND, "gimple_bind", NULL) +DEFGSCODE(GIMPLE_BIND, "gimple_bind", GSS_BIND) /* GIMPLE_CATCH <TYPES, HANDLER> represents a typed exception handler. TYPES is the type (or list of types) handled. HANDLER is the sequence of statements that handle these types. */ -DEFGSCODE(GIMPLE_CATCH, "gimple_catch", NULL) +DEFGSCODE(GIMPLE_CATCH, "gimple_catch", GSS_CATCH) /* GIMPLE_EH_FILTER <TYPES, FAILURE> represents an exception specification. TYPES is a list of allowed types and FAILURE is the sequence of statements to execute on failure. */ -DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter", NULL) +DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter", GSS_EH_FILTER) /* GIMPLE_PHI <RESULT, ARG1, ..., ARGN> represents the PHI node @@ -166,11 +155,11 @@ DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_filter", NULL) exactly the same as the number of incoming edges to the basic block holding the PHI node. Every argument is either an SSA name or a tree node of class tcc_constant. */ -DEFGSCODE(GIMPLE_PHI, "gimple_phi", NULL) +DEFGSCODE(GIMPLE_PHI, "gimple_phi", GSS_PHI) /* GIMPLE_RESX <REGION> resumes execution after an exception. REGION is the region number being left. */ -DEFGSCODE(GIMPLE_RESX, "gimple_resx", NULL) +DEFGSCODE(GIMPLE_RESX, "gimple_resx", GSS_RESX) /* GIMPLE_TRY <TRY_KIND, EVAL, CLEANUP> represents a try/catch or a try/finally statement. @@ -185,10 +174,10 @@ DEFGSCODE(GIMPLE_RESX, "gimple_resx", NULL) GIMPLE_TRY_FINALLY, CLEANUP is always executed after executing EVAL (regardless of whether EVAL finished normally, or jumped out or an exception was thrown). */ -DEFGSCODE(GIMPLE_TRY, "gimple_try", NULL) +DEFGSCODE(GIMPLE_TRY, "gimple_try", GSS_TRY) /* GIMPLE_NOP represents the "do nothing" statement. */ -DEFGSCODE(GIMPLE_NOP, "gimple_nop", NULL) +DEFGSCODE(GIMPLE_NOP, "gimple_nop", GSS_BASE) /* IMPORTANT. @@ -206,12 +195,14 @@ DEFGSCODE(GIMPLE_NOP, "gimple_nop", NULL) GIMPLE_OMP_LOAD (tmp, mem) val = some computations involving tmp; GIMPLE_OMP_STORE (val). */ -DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load", NULL) -DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store", NULL) +DEFGSCODE(GIMPLE_OMP_ATOMIC_LOAD, "gimple_omp_atomic_load", + GSS_OMP_ATOMIC_LOAD) +DEFGSCODE(GIMPLE_OMP_ATOMIC_STORE, "gimple_omp_atomic_store", + GSS_OMP_ATOMIC_STORE) /* GIMPLE_OMP_CONTINUE marks the location of the loop or sections iteration in partially lowered OpenMP code. */ -DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue", NULL) +DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue", GSS_OMP_CONTINUE) /* GIMPLE_OMP_CRITICAL <NAME, BODY> represents @@ -219,7 +210,7 @@ DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue", NULL) NAME is the name given to the critical section. BODY is the sequence of statements that are inside the critical section. */ -DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", NULL) +DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", GSS_OMP_CRITICAL) /* GIMPLE_OMP_FOR <BODY, CLAUSES, INDEX, INITIAL, FINAL, COND, INCR, PRE_BODY> represents @@ -256,15 +247,15 @@ DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical", NULL) expressions that are evaluated without any synchronization. The evaluation order, frequency of evaluation and side-effects are unspecified by the standard. */ -DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", NULL) +DEFGSCODE(GIMPLE_OMP_FOR, "gimple_omp_for", GSS_OMP_FOR) /* GIMPLE_OMP_MASTER <BODY> represents #pragma omp master. BODY is the sequence of statements to execute in the master section. */ -DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", NULL) +DEFGSCODE(GIMPLE_OMP_MASTER, "gimple_omp_master", GSS_OMP) /* GIMPLE_OMP_ORDERED <BODY> represents #pragma omp ordered. BODY is the sequence of statements to execute in the ordered section. */ -DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", NULL) +DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP) /* GIMPLE_OMP_PARALLEL <BODY, CLAUSES, CHILD_FN, DATA_ARG> represents @@ -282,7 +273,7 @@ DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", NULL) DATA_ARG is a local variable in the parent function containing data to be shared with CHILD_FN. This is used to implement all the data sharing clauses. */ -DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", NULL) +DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL) /* GIMPLE_OMP_TASK <BODY, CLAUSES, CHILD_FN, DATA_ARG, COPY_FN, ARG_SIZE, ARG_ALIGN> represents @@ -308,14 +299,14 @@ DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", NULL) ARG_SIZE and ARG_ALIGN are the size and alignment of the incoming data area allocated by GOMP_task and passed to CHILD_FN. */ -DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", NULL) +DEFGSCODE(GIMPLE_OMP_TASK, "gimple_omp_task", GSS_OMP_TASK) /* OMP_RETURN marks the end of an OpenMP directive. */ -DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", NULL) +DEFGSCODE(GIMPLE_OMP_RETURN, "gimple_omp_return", GSS_BASE) /* OMP_SECTION <BODY> represents #pragma omp section. BODY is the sequence of statements in the section body. */ -DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", NULL) +DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP) /* OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections. @@ -323,28 +314,28 @@ DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", NULL) CLAUSES is a TREE_LIST node holding the list of associated clauses. CONTROL is a VAR_DECL used for deciding which of the sections to execute. */ -DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", NULL) +DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", GSS_OMP_SECTIONS) /* GIMPLE_OMP_SECTIONS_SWITCH is a marker placed immediately after OMP_SECTIONS. It represents the GIMPLE_SWITCH used to decide which branch is taken. */ -DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", NULL) +DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE) /* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single BODY is the sequence of statements inside the single section. CLAUSES is a TREE_LIST node holding the associated clauses. */ -DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", NULL) +DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE) /* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction. PREDICT is one of the predictors from predict.def. OUTCOME is NOT_TAKEN or TAKEN. */ -DEFGSCODE(GIMPLE_PREDICT, "gimple_predict", NULL) +DEFGSCODE(GIMPLE_PREDICT, "gimple_predict", GSS_BASE) /* This node represents a cleanup expression. It is ONLY USED INTERNALLY by the gimplifier as a placeholder for cleanups, and its uses will be cleaned up by the time gimplification is done. This tuple should not exist outside of the gimplifier proper. */ -DEFGSCODE(GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr", NULL) +DEFGSCODE(GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr", GSS_WCE) diff --git a/gcc/gimple.h b/gcc/gimple.h index 6dce0b78357..8ca1f288084 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -714,12 +714,12 @@ struct GTY(()) gimple_statement_omp_atomic_store { tree val; }; +#define DEFGSSTRUCT(SYM, STRUCT, HAS_TREE_OP) SYM, enum gimple_statement_structure_enum { -#define DEFGSSTRUCT(SYM, STRING) SYM, #include "gsstruct.def" -#undef DEFGSSTRUCT LAST_GSS_ENUM }; +#undef DEFGSSTRUCT /* Define the overall contents of a gimple tuple. It may be any of the @@ -750,6 +750,14 @@ union GTY ((desc ("gimple_statement_structure (&%h)"))) gimple_statement_d { }; /* In gimple.c. */ + +/* Offset in bytes to the location of the operand vector. + Zero if there is no operand vector for this tuple structure. */ +extern size_t const gimple_ops_offset_[]; + +/* Map GIMPLE codes to GSS codes. */ +extern enum gimple_statement_structure_enum const gss_for_code_[]; + gimple gimple_build_return (tree); gimple gimple_build_assign_stat (tree, tree MEM_STAT_DECL); @@ -801,7 +809,6 @@ gimple gimple_build_cdt (tree, tree); gimple gimple_build_omp_atomic_load (tree, tree); gimple gimple_build_omp_atomic_store (tree); gimple gimple_build_predict (enum br_predictor, enum prediction); -enum gimple_statement_structure_enum gimple_statement_structure (gimple); enum gimple_statement_structure_enum gss_for_assign (enum tree_code); void sort_case_labels (VEC(tree,heap) *); void gimple_set_body (tree, gimple_seq); @@ -1023,6 +1030,25 @@ gimple_code (const_gimple g) } +/* Return the GSS code used by a GIMPLE code. */ + +static inline enum gimple_statement_structure_enum +gss_for_code (enum gimple_code code) +{ + gcc_assert ((unsigned int)code < LAST_AND_UNUSED_GIMPLE_CODE); + return gss_for_code_[code]; +} + + +/* Return which GSS code is used by GS. */ + +static inline enum gimple_statement_structure_enum +gimple_statement_structure (gimple gs) +{ + return gss_for_code (gimple_code (gs)); +} + + /* Return true if statement G has sub-statements. This is only true for High GIMPLE statements. */ @@ -1557,16 +1583,15 @@ gimple_set_num_ops (gimple gs, unsigned num_ops) static inline tree * gimple_ops (gimple gs) { - /* Offset in bytes to the location of the operand vector in every - tuple structure. Defined in gimple.c */ - extern size_t const gimple_ops_offset_[]; - - if (!gimple_has_ops (gs)) - return NULL; + size_t off; /* All the tuples have their operand vector at the very bottom - of the structure. */ - return ((tree *) ((char *) gs + gimple_ops_offset_[gimple_code (gs)])); + of the structure. Note that those structures that do not + have an operand vector have a zero offset. */ + off = gimple_ops_offset_[gimple_statement_structure (gs)]; + gcc_assert (off != 0); + + return (tree *) ((char *) gs + off); } diff --git a/gcc/gsstruct.def b/gcc/gsstruct.def index 58f4476c25e..97875c9e036 100644 --- a/gcc/gsstruct.def +++ b/gcc/gsstruct.def @@ -21,28 +21,28 @@ along with GCC; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ /* The format of this file is - DEFGSSTRUCT(GSS_enumeration value, printable name). + DEFGSSTRUCT(GSS enumeration value, structure name, has-tree-operands). Each enum value should correspond with a single member of the union gimple_statement_d. */ -DEFGSSTRUCT(GSS_BASE, "base") -DEFGSSTRUCT(GSS_WITH_OPS, "with_ops") -DEFGSSTRUCT(GSS_WITH_MEM_OPS, "with_mem_ops") -DEFGSSTRUCT(GSS_OMP, "omp") -DEFGSSTRUCT(GSS_BIND, "bind") -DEFGSSTRUCT(GSS_CATCH, "catch") -DEFGSSTRUCT(GSS_EH_FILTER, "eh_filter") -DEFGSSTRUCT(GSS_PHI, "phi") -DEFGSSTRUCT(GSS_RESX, "resx") -DEFGSSTRUCT(GSS_TRY, "try") -DEFGSSTRUCT(GSS_WCE, "with_cleanup_expression") -DEFGSSTRUCT(GSS_ASM, "asm") -DEFGSSTRUCT(GSS_OMP_CRITICAL, "omp_critical") -DEFGSSTRUCT(GSS_OMP_FOR, "omp_for") -DEFGSSTRUCT(GSS_OMP_PARALLEL, "omp_parallel") -DEFGSSTRUCT(GSS_OMP_TASK, "omp_task") -DEFGSSTRUCT(GSS_OMP_SECTIONS, "sections") -DEFGSSTRUCT(GSS_OMP_SINGLE, "single") -DEFGSSTRUCT(GSS_OMP_CONTINUE, "omp_continue") -DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, "omp_atomic_load") -DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, "omp_atomic_store") +DEFGSSTRUCT(GSS_BASE, gimple_statement_base, false) +DEFGSSTRUCT(GSS_WITH_OPS, gimple_statement_with_ops, true) +DEFGSSTRUCT(GSS_WITH_MEM_OPS, gimple_statement_with_memory_ops, true) +DEFGSSTRUCT(GSS_ASM, gimple_statement_asm, true) +DEFGSSTRUCT(GSS_BIND, gimple_statement_bind, false) +DEFGSSTRUCT(GSS_PHI, gimple_statement_phi, false) +DEFGSSTRUCT(GSS_TRY, gimple_statement_try, false) +DEFGSSTRUCT(GSS_CATCH, gimple_statement_catch, false) +DEFGSSTRUCT(GSS_EH_FILTER, gimple_statement_eh_filter, false) +DEFGSSTRUCT(GSS_RESX, gimple_statement_resx, false) +DEFGSSTRUCT(GSS_WCE, gimple_statement_wce, false) +DEFGSSTRUCT(GSS_OMP, gimple_statement_omp, false) +DEFGSSTRUCT(GSS_OMP_CRITICAL, gimple_statement_omp_critical, false) +DEFGSSTRUCT(GSS_OMP_FOR, gimple_statement_omp_for, false) +DEFGSSTRUCT(GSS_OMP_PARALLEL, gimple_statement_omp_parallel, false) +DEFGSSTRUCT(GSS_OMP_TASK, gimple_statement_omp_task, false) +DEFGSSTRUCT(GSS_OMP_SECTIONS, gimple_statement_omp_sections, false) +DEFGSSTRUCT(GSS_OMP_SINGLE, gimple_statement_omp_single, false) +DEFGSSTRUCT(GSS_OMP_CONTINUE, gimple_statement_omp_continue, false) +DEFGSSTRUCT(GSS_OMP_ATOMIC_LOAD, gimple_statement_omp_atomic_load, false) +DEFGSSTRUCT(GSS_OMP_ATOMIC_STORE, gimple_statement_omp_atomic_store, false) diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index bce5c7f6294..6d84e5643b5 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -662,7 +662,7 @@ print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set) { int i, start; - fprintf (file, title); + fputs (title, file); for (start = -1, i = 0; i < FIRST_PSEUDO_REGISTER; i++) { if (TEST_HARD_REG_BIT (set, i)) @@ -682,7 +682,7 @@ print_hard_reg_set (FILE *file, const char *title, HARD_REG_SET set) start = -1; } } - fprintf (file, "\n"); + putc ('\n', file); } /* Print information about allocno or only regno (if REG_P) conflicts @@ -709,9 +709,9 @@ print_conflicts (FILE *file, bool reg_p) fprintf (file, "b%d", bb->index); else fprintf (file, "l%d", ALLOCNO_LOOP_TREE_NODE (a)->loop->num); - fprintf (file, ")"); + putc (')', file); } - fprintf (file, " conflicts:"); + fputs (" conflicts:", file); if (ALLOCNO_CONFLICT_ALLOCNO_ARRAY (a) != NULL) FOR_EACH_ALLOCNO_CONFLICT (a, conflict_a, aci) { @@ -743,7 +743,7 @@ print_conflicts (FILE *file, bool reg_p) print_hard_reg_set (file, ";; conflict hard regs:", conflicting_hard_regs); } - fprintf (file, "\n"); + putc ('\n', file); } /* Print information about allocno or only regno (if REG_P) conflicts diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 569b5fe16fe..6b7d930ba28 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,13 @@ +2009-09-13 Richard Guenther <rguenther@suse.de> + Rafael Avila de Espindola <espindola@google.com> + + * decl.c (do_nothing): Remove. + (java_init_decl_processing): Do not set lang_eh_runtime_type. + * Make-lang.in (lang.o): Add $(EXCEPT_H) dependency. + * lang.c (java_eh_personality): New. + (java_eh_personality_decl): Likewise. + (LANG_HOOKS_EH_PERSONALITY): Define. + 2009-09-03 Diego Novillo <dnovillo@google.com> * lang.c (lang_hooks): Remove const qualifier. diff --git a/gcc/java/Make-lang.in b/gcc/java/Make-lang.in index ff330fda4e5..a56e2b62943 100644 --- a/gcc/java/Make-lang.in +++ b/gcc/java/Make-lang.in @@ -284,7 +284,7 @@ java/jvgenmain.o: java/jvgenmain.c $(CONFIG_H) $(JAVA_TREE_H) $(SYSTEM_H) \ coretypes.h $(TM_H) intl.h java/lang.o: java/lang.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h input.h \ toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(EXPR_H) $(DIAGNOSTIC_H) \ - langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h + langhooks.h $(LANGHOOKS_DEF_H) gt-java-lang.h opts.h options.h $(EXCEPT_H) java/mangle.o: java/mangle.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) $(SYSTEM_H) \ coretypes.h $(TM_H) toplev.h $(GGC_H) gt-java-mangle.h $(LANGHOOKS_DEF_H) java/mangle_name.o: java/mangle_name.c $(CONFIG_H) java/jcf.h $(JAVA_TREE_H) \ diff --git a/gcc/java/decl.c b/gcc/java/decl.c index 4ab67d6cf51..c9ccc9d8556 100644 --- a/gcc/java/decl.c +++ b/gcc/java/decl.c @@ -510,12 +510,6 @@ create_primitive_vtable (const char *name) return r; } -static tree -do_nothing (tree t) -{ - return t; -} - /* Parse the version string and compute the ABI version number. */ static void parse_version (void) @@ -1195,16 +1189,12 @@ java_init_decl_processing (void) 0, NOT_BUILT_IN, NULL, NULL_TREE); /* Initialize variables for except.c. */ - eh_personality_libfunc = init_one_libfunc (USING_SJLJ_EXCEPTIONS - ? "__gcj_personality_sj0" - : "__gcj_personality_v0"); + if (targetm.arm_eabi_unwinder) unwind_resume_libfunc = init_one_libfunc ("__cxa_end_cleanup"); else default_init_unwind_resume_libfunc (); - lang_eh_runtime_type = do_nothing; - initialize_builtins (); soft_fmod_node = built_in_decls[BUILT_IN_FMOD]; diff --git a/gcc/java/lang.c b/gcc/java/lang.c index d97b508b707..504d0295bf0 100644 --- a/gcc/java/lang.c +++ b/gcc/java/lang.c @@ -45,6 +45,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "tree-dump.h" #include "opts.h" #include "options.h" +#include "except.h" static bool java_init (void); static void java_finish (void); @@ -64,6 +65,8 @@ static bool java_decl_ok_for_sibcall (const_tree); static enum classify_record java_classify_record (tree type); +static tree java_eh_personality (void); + #ifndef TARGET_OBJECT_SUFFIX # define TARGET_OBJECT_SUFFIX ".o" #endif @@ -158,6 +161,9 @@ struct GTY(()) language_function { #undef LANG_HOOKS_ATTRIBUTE_TABLE #define LANG_HOOKS_ATTRIBUTE_TABLE java_attribute_table +#undef LANG_HOOKS_EH_PERSONALITY +#define LANG_HOOKS_EH_PERSONALITY java_eh_personality + /* Each front end provides its own. */ struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; @@ -880,4 +886,18 @@ java_classify_record (tree type) return RECORD_IS_CLASS; } +static GTY(()) tree java_eh_personality_decl; + +static tree +java_eh_personality (void) +{ + if (!java_eh_personality_decl) + java_eh_personality_decl + = build_personality_function (USING_SJLJ_EXCEPTIONS + ? "__gcj_personality_sj0" + : "__gcj_personality_v0"); + + return java_eh_personality_decl; +} + #include "gt-java-lang.h" diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h index 63a0dcde20d..dc4fdeef02f 100644 --- a/gcc/langhooks-def.h +++ b/gcc/langhooks-def.h @@ -40,6 +40,7 @@ extern void lhd_do_nothing (void); extern void lhd_do_nothing_t (tree); extern void lhd_do_nothing_i (int); extern void lhd_do_nothing_f (struct function *); +extern tree lhd_pass_through_t (tree); extern bool lhd_post_options (const char **); extern alias_set_type lhd_get_alias_set (tree); extern tree lhd_return_null_tree_v (void); @@ -107,6 +108,8 @@ extern void lhd_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *, #define LANG_HOOKS_EXPR_TO_DECL lhd_expr_to_decl #define LANG_HOOKS_TO_TARGET_CHARSET lhd_to_target_charset #define LANG_HOOKS_INIT_TS lhd_do_nothing +#define LANG_HOOKS_EH_PERSONALITY lhd_gcc_personality +#define LANG_HOOKS_EH_RUNTIME_TYPE lhd_pass_through_t /* Attribute hooks. */ #define LANG_HOOKS_ATTRIBUTE_TABLE NULL @@ -271,6 +274,8 @@ extern tree lhd_make_node (enum tree_code); LANG_HOOKS_BUILTIN_FUNCTION_EXT_SCOPE, \ LANG_HOOKS_INIT_TS, \ LANG_HOOKS_EXPR_TO_DECL, \ + LANG_HOOKS_EH_PERSONALITY, \ + LANG_HOOKS_EH_RUNTIME_TYPE, \ } #endif /* GCC_LANG_HOOKS_DEF_H */ diff --git a/gcc/langhooks.c b/gcc/langhooks.c index 7d2c0b08a01..092a3238592 100644 --- a/gcc/langhooks.c +++ b/gcc/langhooks.c @@ -53,6 +53,13 @@ lhd_do_nothing_t (tree ARG_UNUSED (t)) { } +/* Pass through (tree). */ +tree +lhd_pass_through_t (tree t) +{ + return t; +} + /* Do nothing (int). */ void diff --git a/gcc/langhooks.h b/gcc/langhooks.h index 8342004be96..349a5d8d5a4 100644 --- a/gcc/langhooks.h +++ b/gcc/langhooks.h @@ -414,6 +414,12 @@ struct lang_hooks if in the process TREE_CONSTANT or TREE_SIDE_EFFECTS need updating. */ tree (*expr_to_decl) (tree expr, bool *tc, bool *se); + /* The EH personality function decl. */ + tree (*eh_personality) (void); + + /* Map a type to a runtime object to match type. */ + tree (*eh_runtime_type) (tree); + /* Whenever you add entries here, make sure you adjust langhooks-def.h and langhooks.c accordingly. */ }; diff --git a/gcc/libfuncs.h b/gcc/libfuncs.h index 70621cf2889..997ecb03641 100644 --- a/gcc/libfuncs.h +++ b/gcc/libfuncs.h @@ -31,7 +31,6 @@ enum libfunc_index LTI_setbits, LTI_unwind_resume, - LTI_eh_personality, LTI_setjmp, LTI_longjmp, LTI_unwind_sjlj_register, @@ -61,7 +60,6 @@ extern GTY(()) rtx libfunc_table[LTI_MAX]; #define setbits_libfunc (libfunc_table[LTI_setbits]) #define unwind_resume_libfunc (libfunc_table[LTI_unwind_resume]) -#define eh_personality_libfunc (libfunc_table[LTI_eh_personality]) #define setjmp_libfunc (libfunc_table[LTI_setjmp]) #define longjmp_libfunc (libfunc_table[LTI_longjmp]) #define unwind_sjlj_register_libfunc (libfunc_table[LTI_unwind_sjlj_register]) diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index d499f0a55c9..59317eb200c 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,17 @@ +2009-09-13 Richard Guenther <rguenther@suse.de> + Rafael Avila de Espindola <espindola@google.com> + + * objc-act.c (objc_eh_runtime_type): Export. + (objc_init_exceptions): Remove. Move warning code ... + (objc_begin_try_stmt): ... here + (objc_build_throw_stmt): ... and here. + (objc_eh_personality_decl): New. + (objc_eh_personality): New function. + * objc-act.h (objc_eh_runtime_type): Declare. + (objc_eh_personality): Likewise. + * objc-lang.c (LANG_HOOKS_EH_RUNTIME_TYPE): Define. + (LANG_HOOKS_EH_PERSONALITY): Likewise. + 2009-09-03 Diego Novillo <dnovillo@google.com> * objc-lang.c (lang_hooks): Remove const qualifier. diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 8b1a596c323..f695431030a 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -3483,50 +3483,32 @@ struct objc_try_context static struct objc_try_context *cur_try_context; +static GTY(()) tree objc_eh_personality_decl; + /* This hook, called via lang_eh_runtime_type, generates a runtime object that represents TYPE. For Objective-C, this is just the class name. */ /* ??? Isn't there a class object or some such? Is it easy to get? */ #ifndef OBJCPLUS -static tree +tree objc_eh_runtime_type (tree type) { return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names); } -#endif - -/* Initialize exception handling. */ -static void -objc_init_exceptions (void) +tree +objc_eh_personality (void) { - static bool done = false; - if (done) - return; - done = true; + if (!flag_objc_sjlj_exceptions + && !objc_eh_personality_decl) + objc_eh_personality_decl + = build_personality_function (USING_SJLJ_EXCEPTIONS + ? "__gnu_objc_personality_sj0" + : "__gnu_objc_personality_v0"); - if (flag_objc_sjlj_exceptions) - { - /* On Darwin, ObjC exceptions require a sufficiently recent - version of the runtime, so the user must ask for them explicitly. */ - if (!flag_objc_exceptions) - warning (0, "use %<-fobjc-exceptions%> to enable Objective-C " - "exception syntax"); - } -#ifndef OBJCPLUS - else - { - c_eh_initialized_p = true; - eh_personality_libfunc - = init_one_libfunc (USING_SJLJ_EXCEPTIONS - ? "__gnu_objc_personality_sj0" - : "__gnu_objc_personality_v0"); - default_init_unwind_resume_libfunc (); - using_eh_for_cleanups (); - lang_eh_runtime_type = objc_eh_runtime_type; - } -#endif + return objc_eh_personality_decl; } +#endif /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin, we'll arrange for it to be initialized (and associated with a binding) @@ -3824,7 +3806,14 @@ objc_begin_try_stmt (location_t try_locus, tree body) c->end_try_locus = input_location; cur_try_context = c; - objc_init_exceptions (); + if (flag_objc_sjlj_exceptions) + { + /* On Darwin, ObjC exceptions require a sufficiently recent + version of the runtime, so the user must ask for them explicitly. */ + if (!flag_objc_exceptions) + warning (0, "use %<-fobjc-exceptions%> to enable Objective-C " + "exception syntax"); + } if (flag_objc_sjlj_exceptions) objc_mark_locals_volatile (NULL); @@ -3973,7 +3962,14 @@ objc_build_throw_stmt (location_t loc, tree throw_expr) { tree args; - objc_init_exceptions (); + if (flag_objc_sjlj_exceptions) + { + /* On Darwin, ObjC exceptions require a sufficiently recent + version of the runtime, so the user must ask for them explicitly. */ + if (!flag_objc_exceptions) + warning (0, "use %<-fobjc-exceptions%> to enable Objective-C " + "exception syntax"); + } if (throw_expr == NULL) { diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h index fb929342b99..f0970f90bfd 100644 --- a/gcc/objc/objc-act.h +++ b/gcc/objc/objc-act.h @@ -32,6 +32,8 @@ const char *objc_printable_name (tree, int); void objc_finish_file (void); tree objc_fold_obj_type_ref (tree, tree); int objc_gimplify_expr (tree *, gimple_seq *, gimple_seq *); +tree objc_eh_runtime_type (tree); +tree objc_eh_personality (void); /* NB: The remaining public functions are prototyped in c-common.h, for the benefit of stub-objc.c and objc-act.c. */ diff --git a/gcc/objc/objc-lang.c b/gcc/objc/objc-lang.c index 98f46d741ab..acb1c84649d 100644 --- a/gcc/objc/objc-lang.c +++ b/gcc/objc/objc-lang.c @@ -51,6 +51,13 @@ static void objc_init_ts (void); #undef LANG_HOOKS_INIT_TS #define LANG_HOOKS_INIT_TS objc_init_ts +#ifndef OBJCPLUS +#undef LANG_HOOKS_EH_PERSONALITY +#define LANG_HOOKS_EH_PERSONALITY objc_eh_personality +#undef LANG_HOOKS_EH_RUNTIME_TYPE +#define LANG_HOOKS_EH_RUNTIME_TYPE objc_eh_runtime_type +#endif + /* Each front end provides its own lang hook initializer. */ struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; diff --git a/gcc/optabs.c b/gcc/optabs.c index 61d8bcfe298..35f95f2e3d4 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -6023,6 +6023,28 @@ libfunc_decl_eq (const void *entry1, const void *entry2) return DECL_NAME ((const_tree) entry1) == (const_tree) entry2; } +/* Build a decl for a libfunc named NAME. */ + +tree +build_libfunc_function (const char *name) +{ + tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, + get_identifier (name), + build_function_type (integer_type_node, NULL_TREE)); + /* ??? We don't have any type information except for this is + a function. Pretend this is "int foo()". */ + DECL_ARTIFICIAL (decl) = 1; + DECL_EXTERNAL (decl) = 1; + TREE_PUBLIC (decl) = 1; + gcc_assert (DECL_ASSEMBLER_NAME (decl)); + + /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with + are the flags assigned by targetm.encode_section_info. */ + SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL); + + return decl; +} + rtx init_one_libfunc (const char *name) { @@ -6043,19 +6065,7 @@ init_one_libfunc (const char *name) { /* Create a new decl, so that it can be passed to targetm.encode_section_info. */ - /* ??? We don't have any type information except for this is - a function. Pretend this is "int foo()". */ - decl = build_decl (UNKNOWN_LOCATION, - FUNCTION_DECL, get_identifier (name), - build_function_type (integer_type_node, NULL_TREE)); - DECL_ARTIFICIAL (decl) = 1; - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - - /* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with - are the flags assigned by targetm.encode_section_info. */ - SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL); - + decl = build_libfunc_function (name); *slot = decl; } return XEXP (DECL_RTL (decl), 0); diff --git a/gcc/opts.c b/gcc/opts.c index 601132e14a8..878635f8ca3 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -1512,7 +1512,7 @@ common_handle_option (size_t scode, const char *arg, int value, { NULL, 0 } }; unsigned int * pflags; - char * comma; + const char * comma; unsigned int lang_flag, specific_flag; unsigned int len; unsigned int i; diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index cb09597b579..a75442eb6c7 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -305,9 +305,9 @@ print_rtx (const_rtx in_rtx) break; } } - else if (i == 9 && JUMP_P (in_rtx) && XEXP (in_rtx, i) != NULL) + else if (i == 8 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL) /* Output the JUMP_LABEL reference. */ - fprintf (outfile, "\n -> %d", INSN_UID (XEXP (in_rtx, i))); + fprintf (outfile, "\n -> %d", INSN_UID (JUMP_LABEL (in_rtx))); else if (i == 0 && GET_CODE (in_rtx) == VALUE) { #ifndef GENERATOR_FILE diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8e2266b6024..cc1b26b3b2e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,46 @@ +2009-09-12 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libgfortran/41328 + * gfortran.dg/cr_lf.f90: New test. + +2009-09-11 Michael Matz <matz@suse.de> + + PR middle-end/41275 + * g++.dg/tree-ssa/pr41275.C: New test. + +2009-09-11 Janus Weil <janus@gcc.gnu.org> + + PR fortran/41242 + * gfortran.dg/proc_ptr_comp_21.f90: New. + +2009-09-10 Steven G. Kargl <kargl@gcc.gnu.org> + + PR fortran/31292 + * gfortran.dg/module_procedure_1.f90: New test. + * gfortran.dg/module_procedure_2.f90: Ditto. + * gfortran.dg/generic_14.f90: Move dg-error to new location. + +2009-09-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> + James A. Morrison <phython@gcc.gnu.org> + + PR ada/18302 + * ada/acats/run_all.sh (target_run): Use run_test.exp to execute + commands. + * ada/acats/run_test.exp: New file. + +2009-09-10 Uros Bizjak <ubizjak@gmail.com> + + Revert: + 2009-09-09 Uros Bizjak <ubizjak@gmail.com> + + PR rtl-optimization/39779 + * gcc.dg/pr39979.c: New test. + +2009-09-10 Richard Guenther <rguenther@suse.de> + + PR middle-end/41257 + * g++.dg/torture/pr41257-2.C: New testcase. + 2009-09-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/28293 diff --git a/gcc/testsuite/ada/acats/run_all.sh b/gcc/testsuite/ada/acats/run_all.sh index ddd4da0f300..e28ec7a838a 100755 --- a/gcc/testsuite/ada/acats/run_all.sh +++ b/gcc/testsuite/ada/acats/run_all.sh @@ -13,7 +13,7 @@ gccflags="-O2" gnatflags="-gnatws" target_run () { -$* + eval $EXPECT -f $testdir/run_test.exp $* } # End of customization section. diff --git a/gcc/testsuite/ada/acats/run_test.exp b/gcc/testsuite/ada/acats/run_test.exp new file mode 100644 index 00000000000..07dec27709b --- /dev/null +++ b/gcc/testsuite/ada/acats/run_test.exp @@ -0,0 +1,13 @@ +#!/usr/bin/expect -f + +if {[info exists env(DEJAGNU_TIMEOUT)]} { + set timeout $env(DEJAGNU_TIMEOUT) +} else { + set timeout 300 +} + +spawn -noecho $argv +expect timeout { + send_user "Program timed out.\n" + exit 1 +} diff --git a/gcc/testsuite/g++.dg/torture/pr41257-2.C b/gcc/testsuite/g++.dg/torture/pr41257-2.C new file mode 100644 index 00000000000..230fa5dde49 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr41257-2.C @@ -0,0 +1,16 @@ +/* { dg-do link } */ + +struct A +{ + virtual ~A(); +}; + +struct B : virtual A +{ + virtual ~B() {} +}; + +int main() +{ + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr41275.C b/gcc/testsuite/g++.dg/tree-ssa/pr41275.C new file mode 100644 index 00000000000..d9b3dce8fb1 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr41275.C @@ -0,0 +1,16 @@ +// PR middle-end/41275 +// { dg-do compile } +// { dg-options "-O2" } +// this used to ICE +struct ErrmsgWindow +{ + virtual ~ErrmsgWindow() + { + extern int _switch_mode_errorstr; + _switch_mode_errorstr = 42; + } +}; +void ShowErrorMessage(void) +{ + ErrmsgWindow w; +} diff --git a/gcc/testsuite/gcc.dg/pr39779.c b/gcc/testsuite/gcc.dg/pr39779.c deleted file mode 100644 index 7d3cef17c67..00000000000 --- a/gcc/testsuite/gcc.dg/pr39779.c +++ /dev/null @@ -1,8 +0,0 @@ -/* { dg-do compile } */ -/* { dg-options "-w" } */ - -int test (char v1) -{ - v1 >>= 0xdebecced; - return v1; -} diff --git a/gcc/testsuite/gfortran.dg/cr_lf.f90 b/gcc/testsuite/gfortran.dg/cr_lf.f90 new file mode 100644 index 00000000000..855e7036095 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/cr_lf.f90 @@ -0,0 +1,36 @@ +! { dg-do run } +! { dg-options "-fbackslash" } +! PR41328 and PR41168 Improper read of CR-LF sequences. +! Test case prepared by Jerry DeLisle <jvdelisle@gcc.gnu.org> +program main + implicit none + integer :: iostat, n_chars_read + character(len=1) :: buffer(64) = "" + open( unit=10, form="formatted", access="stream", status="scratch") + write(10, fmt="(a)", advance="no") "a\rb\rc\r" + rewind(10) + + read( unit=10, fmt='(64A)', advance='NO', iostat=iostat, & + size=n_chars_read ) buffer + if (n_chars_read.ne.1) call abort + if (any(buffer(1:n_chars_read).ne."a")) call abort + if (.not.is_iostat_eor(iostat)) call abort + + read( unit=10, fmt='(64A)', advance='NO', iostat=iostat, & + size=n_chars_read ) buffer + if (n_chars_read.ne.1) call abort + if (any(buffer(1:n_chars_read).ne."b")) call abort + if (.not.is_iostat_eor(iostat)) call abort + + read( unit=10, fmt='(64A)', advance='NO', iostat=iostat, & + size=n_chars_read ) buffer + if (n_chars_read.ne.1) call abort + if (any(buffer(1:n_chars_read).ne."c")) call abort + if (.not.is_iostat_eor(iostat)) call abort + + read( unit=10, fmt='(64A)', advance='NO', iostat=iostat, & + size=n_chars_read ) buffer + if (n_chars_read.ne.0) call abort + if (any(buffer(1:n_chars_read).ne."a")) call abort + if (.not.is_iostat_end(iostat)) call abort +end program main diff --git a/gcc/testsuite/gfortran.dg/generic_14.f90 b/gcc/testsuite/gfortran.dg/generic_14.f90 index 3198da1dafc..e95f6f2edeb 100644 --- a/gcc/testsuite/gfortran.dg/generic_14.f90 +++ b/gcc/testsuite/gfortran.dg/generic_14.f90 @@ -85,18 +85,18 @@ end module f module g implicit none - external wrong_b ! { dg-error "has no explicit interface" } + external wrong_b interface gen_wrong_5 - module procedure wrong_b ! wrong, see above + module procedure wrong_b ! { dg-error "has no explicit interface" } end interface gen_wrong_5 end module g module h implicit none - external wrong_c ! { dg-error "has no explicit interface" } + external wrong_c real wrong_c interface gen_wrong_6 - module procedure wrong_c ! wrong, see above + module procedure wrong_c ! { dg-error "has no explicit interface" } end interface gen_wrong_6 end module h diff --git a/gcc/testsuite/gfortran.dg/module_procedure_1.f90 b/gcc/testsuite/gfortran.dg/module_procedure_1.f90 new file mode 100644 index 00000000000..5e1fa15c729 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/module_procedure_1.f90 @@ -0,0 +1,53 @@ +! { dg-do run } +! Modified program from http://groups.google.com/group/\ +! comp.lang.fortran/browse_frm/thread/423e4392dc965ab7# +! +module myoperator + contains + function dadd(arg1,arg2) + integer ::dadd(2) + integer, intent(in) :: arg1(2), arg2(2) + dadd(1)=arg1(1)+arg2(1) + dadd(2)=arg1(2)+arg2(2) + end function dadd +end module myoperator + +program test_interface + + use myoperator + + implicit none + + interface operator (.myadd.) + module procedure dadd + end interface + + integer input1(2), input2(2), mysum(2) + + input1 = (/0,1/) + input2 = (/3,3/) + mysum = input1 .myadd. input2 + if (mysum(1) /= 3 .and. mysum(2) /= 4) call abort + + call test_sub(input1, input2) + +end program test_interface + +subroutine test_sub(input1, input2) + + use myoperator + + implicit none + + interface operator (.myadd.) + module procedure dadd + end interface + + integer, intent(in) :: input1(2), input2(2) + integer mysum(2) + + mysum = input1 .myadd. input2 + if (mysum(1) /= 3 .and. mysum(2) /= 4) call abort + +end subroutine test_sub +! { dg-final { cleanup-modules "myoperator" } } diff --git a/gcc/testsuite/gfortran.dg/module_procedure_2.f90 b/gcc/testsuite/gfortran.dg/module_procedure_2.f90 new file mode 100644 index 00000000000..8f6db25fb13 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/module_procedure_2.f90 @@ -0,0 +1,8 @@ +! { dg-do compile } +program test + implicit none + intrinsic sin + interface gen2 + module procedure sin ! { dg-error "cannot be a MODULE PROCEDURE" } + end interface gen2 +end program test diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_comp_21.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_comp_21.f90 new file mode 100644 index 00000000000..c000896d549 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/proc_ptr_comp_21.f90 @@ -0,0 +1,28 @@ +! { dg-do compile } +! +! PR 41242: [4.5 Regression] PPC call rejected (related to user-defined assignment?) +! +! Original test case by Juergen Reuter <reuter@physik.uni-freiburg.de> +! Modified by Janus Weil <janus@gcc.gnu.org> + + type :: nf_t + procedure(integer), nopass, pointer :: get_n_in + end type + + interface assignment(=) + procedure op_assign + end interface + + type(nf_t) :: prc_lib + prc_lib = "foobar" + print *, prc_lib%get_n_in() + +contains + + elemental subroutine op_assign (str, ch) + type(nf_t), intent(out) :: str + character(len=*), intent(in) :: ch + end subroutine + +end + diff --git a/gcc/toplev.c b/gcc/toplev.c index 8b4bc10085a..a62a8e1adb5 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -723,7 +723,7 @@ output_file_directive (FILE *asm_file, const char *input_name) #else fprintf (asm_file, "\t.file\t"); output_quoted_string (asm_file, na); - fputc ('\n', asm_file); + putc ('\n', asm_file); #endif } @@ -1283,7 +1283,7 @@ print_to_asm_out_file (print_switch_type type, const char * text) case SWITCH_TYPE_ENABLED: if (prepend_sep) fputc (' ', asm_out_file); - fprintf (asm_out_file, text); + fputs (text, asm_out_file); /* No need to return the length here as print_single_switch has already done it. */ return 0; @@ -1312,7 +1312,7 @@ print_to_stderr (print_switch_type type, const char * text) /* Drop through. */ case SWITCH_TYPE_DESCRIPTIVE: - fprintf (stderr, text); + fputs (text, stderr); /* No need to return the length here as print_single_switch has already done it. */ return 0; @@ -1472,7 +1472,7 @@ init_asm_output (const char *name) into the assembler file as comments. */ print_version (asm_out_file, ASM_COMMENT_START); print_switch_values (print_to_asm_out_file); - fprintf (asm_out_file, "\n"); + putc ('\n', asm_out_file); } #endif } diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 524422f1ec4..02daee092ef 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -1354,6 +1354,24 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b) && DECL_NONLOCAL (gimple_label_label (stmt))) return false; + /* Examine the labels at the beginning of B. */ + for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi)) + { + tree lab; + stmt = gsi_stmt (gsi); + if (gimple_code (stmt) != GIMPLE_LABEL) + break; + lab = gimple_label_label (stmt); + + /* Do not remove user labels. */ + if (!DECL_ARTIFICIAL (lab)) + return false; + } + + /* Protect the loop latches. */ + if (current_loops && b->loop_father->latch == b) + return false; + /* It must be possible to eliminate all phi nodes in B. If ssa form is not up-to-date, we cannot eliminate any phis; however, if only some symbols as whole are marked for renaming, this is not a problem, @@ -1377,21 +1395,6 @@ gimple_can_merge_blocks_p (basic_block a, basic_block b) } } - /* Do not remove user labels. */ - for (gsi = gsi_start_bb (b); !gsi_end_p (gsi); gsi_next (&gsi)) - { - stmt = gsi_stmt (gsi); - if (gimple_code (stmt) != GIMPLE_LABEL) - break; - if (!DECL_ARTIFICIAL (gimple_label_label (stmt))) - return false; - } - - /* Protect the loop latches. */ - if (current_loops - && b->loop_father->latch == b) - return false; - return true; } @@ -2732,11 +2735,17 @@ gimple_cfg2vcg (FILE *file) bool is_ctrl_stmt (gimple t) { - return gimple_code (t) == GIMPLE_COND - || gimple_code (t) == GIMPLE_SWITCH - || gimple_code (t) == GIMPLE_GOTO - || gimple_code (t) == GIMPLE_RETURN - || gimple_code (t) == GIMPLE_RESX; + switch (gimple_code (t)) + { + case GIMPLE_COND: + case GIMPLE_SWITCH: + case GIMPLE_GOTO: + case GIMPLE_RETURN: + case GIMPLE_RESX: + return true; + default: + return false; + } } @@ -2972,11 +2981,15 @@ static basic_block split_edge_bb_loc (edge edge_in) { basic_block dest = edge_in->dest; + basic_block dest_prev = dest->prev_bb; - if (dest->prev_bb && find_edge (dest->prev_bb, dest)) - return edge_in->src; - else - return dest->prev_bb; + if (dest_prev) + { + edge e = find_edge (dest_prev, dest); + if (e && !(e->flags & EDGE_COMPLEX)) + return edge_in->src; + } + return dest_prev; } /* Split a (typically critical) edge EDGE_IN. Return the new block. @@ -5032,16 +5045,19 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) if (e->flags & EDGE_ABNORMAL) return NULL; - if (e->src != ENTRY_BLOCK_PTR - && (ret = gimple_try_redirect_by_replacing_jump (e, dest))) - return ret; - if (e->dest == dest) return NULL; if (e->flags & EDGE_EH) return redirect_eh_edge (e, dest); + if (e->src != ENTRY_BLOCK_PTR) + { + ret = gimple_try_redirect_by_replacing_jump (e, dest); + if (ret) + return ret; + } + gsi = gsi_last_bb (bb); stmt = gsi_end_p (gsi) ? NULL : gsi_stmt (gsi); @@ -6426,7 +6442,7 @@ dump_function_to_file (tree fn, FILE *file, int flags) print_node (file, "", fn, 2); dsf = DECL_STRUCT_FUNCTION (fn); - if (dsf && (flags & TDF_DETAILS)) + if (dsf && (flags & TDF_EH)) dump_eh_tree (file, dsf); if (flags & TDF_RAW && !gimple_has_body_p (fn)) @@ -7250,7 +7266,7 @@ split_critical_edges (void) Go ahead and split them too. This matches the logic in gimple_find_edge_insert_loc. */ else if ((!single_pred_p (e->dest) - || phi_nodes (e->dest) + || !gimple_seq_empty_p (phi_nodes (e->dest)) || e->dest == EXIT_BLOCK_PTR) && e->src != ENTRY_BLOCK_PTR && !(e->flags & EDGE_ABNORMAL)) diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index d9baf711379..ac87f424dcd 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -1939,6 +1939,14 @@ lower_eh_constructs (void) htab_delete (finally_tree); collect_eh_region_array (); + + /* If this function needs a language specific EH personality routine + and the frontend didn't already set one do so now. */ + if (function_needs_eh_personality (cfun) == eh_personality_lang + && !DECL_FUNCTION_PERSONALITY (current_function_decl)) + DECL_FUNCTION_PERSONALITY (current_function_decl) + = lang_hooks.eh_personality (); + return 0; } diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index fbd973b4281..b83c52f5370 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -536,6 +536,7 @@ remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id) if (can_be_nonlocal (old_var, id)) { if (TREE_CODE (old_var) == VAR_DECL + && ! DECL_EXTERNAL (old_var) && (var_ann (old_var) || !gimple_in_ssa_p (cfun))) cfun->local_decls = tree_cons (NULL_TREE, old_var, cfun->local_decls); @@ -3504,6 +3505,13 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) cg_edge = cgraph_edge (id->dst_node, stmt); + /* Don't inline functions with different EH personalities. */ + if (DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl) + && DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl) + && (DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl) + != DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl))) + goto egress; + /* Don't try to inline functions that are not well-suited to inlining. */ if (!cgraph_inline_p (cg_edge, &reason)) @@ -3545,6 +3553,11 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) /* We will be inlining this callee. */ id->eh_region = lookup_stmt_eh_region (stmt); + /* Update the callers EH personality. */ + if (DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl)) + DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl) + = DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl); + /* Split the block holding the GIMPLE_CALL. */ e = split_block (bb, stmt); bb = e->src; @@ -4729,6 +4742,7 @@ tree_function_versioning (tree old_decl, tree new_decl, DECL_ARTIFICIAL (new_decl) = 1; DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl); + DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl); /* Prepare the data structures for the tree copy. */ memset (&id, 0, sizeof (id)); @@ -4999,6 +5013,18 @@ tree_can_inline_p (struct cgraph_edge *e) caller = e->caller->decl; callee = e->callee->decl; + /* We cannot inline a function that uses a different EH personality + than the caller. */ + if (DECL_FUNCTION_PERSONALITY (caller) + && DECL_FUNCTION_PERSONALITY (callee) + && (DECL_FUNCTION_PERSONALITY (caller) + != DECL_FUNCTION_PERSONALITY (callee))) + { + e->inline_failed = CIF_UNSPECIFIED; + gimple_call_set_cannot_inline (e->call_stmt, true); + return false; + } + /* Allow the backend to decide if inlining is ok. */ if (!targetm.target_option.can_inline_p (caller, callee)) { diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index 1309e822fe2..3409ef83259 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -875,7 +875,7 @@ do_switchconv (void) "SWITCH statement (%s:%d) : ------- \n", loc.file, loc.line); print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); - fprintf (dump_file, "\n"); + putc ('\n', dump_file); } info.reason = NULL; @@ -883,8 +883,8 @@ do_switchconv (void) { if (dump_file) { - fprintf (dump_file, "Switch converted\n"); - fprintf (dump_file, "--------------------------------\n"); + fputs ("Switch converted\n", dump_file); + fputs ("--------------------------------\n", dump_file); } } else @@ -892,9 +892,9 @@ do_switchconv (void) if (dump_file) { gcc_assert (info.reason); - fprintf (dump_file, "Bailing out - "); - fprintf (dump_file, info.reason); - fprintf (dump_file, "--------------------------------\n"); + fputs ("Bailing out - ", dump_file); + fputs (info.reason, dump_file); + fputs ("--------------------------------\n", dump_file); } } } diff --git a/gcc/tree.c b/gcc/tree.c index 17009c6b8e4..98a683dea9d 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1905,6 +1905,17 @@ purpose_member (const_tree elem, tree list) return NULL_TREE; } +/* Returns element number IDX (zero-origin) of chain CHAIN, or + NULL_TREE. */ + +tree +chain_index (int idx, tree chain) +{ + for (; chain && idx > 0; --idx) + chain = TREE_CHAIN (chain); + return chain; +} + /* Return nonzero if ELEM is part of the chain CHAIN. */ int @@ -4447,6 +4458,9 @@ free_lang_data_in_decl (tree decl) struct free_lang_data_d { + /* Worklist to avoid excessive recursion. */ + VEC(tree,heap) *worklist; + /* Set of traversed objects. Used to avoid duplicate visits. */ struct pointer_set_t *pset; @@ -4508,6 +4522,9 @@ add_tree_to_fld_list (tree t, struct free_lang_data_d *fld) gcc_unreachable (); } +#define PUSH(t) \ + if (t && !pointer_set_contains (fld->pset, t)) \ + VEC_safe_push (tree, heap, fld->worklist, (t)) /* Operand callback helper for free_lang_data_in_node. *TP is the subtree operand being considered. */ @@ -4518,49 +4535,49 @@ find_decls_types_r (tree *tp, int *ws ATTRIBUTE_UNUSED, void *data) tree t = *tp; struct free_lang_data_d *fld = (struct free_lang_data_d *) data; + if (TREE_CODE (t) == TREE_LIST) + return NULL_TREE; + if (DECL_P (t)) { /* Note that walk_tree does not traverse every possible field in decls, so we have to do our own traversals here. */ add_tree_to_fld_list (t, fld); - walk_tree (&DECL_NAME (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_CONTEXT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_SIZE (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_SIZE_UNIT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_INITIAL (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_ATTRIBUTES (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_ABSTRACT_ORIGIN (t), find_decls_types_r, fld, fld->pset); + PUSH (DECL_NAME (t)); + PUSH (DECL_CONTEXT (t)); + PUSH (DECL_SIZE (t)); + PUSH (DECL_SIZE_UNIT (t)); + PUSH (DECL_INITIAL(t)); + PUSH (DECL_ATTRIBUTES (t)); + PUSH (DECL_ABSTRACT_ORIGIN (t)); if (TREE_CODE (t) == FUNCTION_DECL) { - walk_tree (&DECL_ARGUMENTS (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_RESULT (t), find_decls_types_r, fld, fld->pset); + PUSH (DECL_ARGUMENTS (t)); + PUSH (DECL_RESULT (t)); } else if (TREE_CODE (t) == TYPE_DECL) { - walk_tree (&DECL_ARGUMENT_FLD (t), find_decls_types_r, fld, - fld->pset); - walk_tree (&DECL_VINDEX (t), find_decls_types_r, fld, fld->pset); + PUSH (DECL_ARGUMENT_FLD (t)); + PUSH (DECL_VINDEX (t)); } else if (TREE_CODE (t) == FIELD_DECL) { - walk_tree (&DECL_FIELD_OFFSET (t), find_decls_types_r, fld, - fld->pset); - walk_tree (&DECL_BIT_FIELD_TYPE (t), find_decls_types_r, fld, - fld->pset); - walk_tree (&DECL_QUALIFIER (t), find_decls_types_r, fld, fld->pset); - walk_tree (&DECL_FIELD_BIT_OFFSET (t), find_decls_types_r, fld, - fld->pset); - walk_tree (&DECL_FCONTEXT (t), find_decls_types_r, fld, fld->pset); + PUSH (DECL_FIELD_OFFSET (t)); + PUSH (DECL_BIT_FIELD_TYPE (t)); + PUSH (DECL_QUALIFIER (t)); + PUSH (DECL_FIELD_BIT_OFFSET (t)); + PUSH (DECL_FCONTEXT (t)); } else if (TREE_CODE (t) == VAR_DECL) { - walk_tree (&DECL_SECTION_NAME (t), find_decls_types_r, fld, - fld->pset); - walk_tree (&DECL_COMDAT_GROUP (t), find_decls_types_r, fld, - fld->pset); + PUSH (DECL_SECTION_NAME (t)); + PUSH (DECL_COMDAT_GROUP (t)); } + + PUSH (TREE_CHAIN (t)); + *ws = 0; } else if (TYPE_P (t)) { @@ -4568,36 +4585,55 @@ find_decls_types_r (tree *tp, int *ws ATTRIBUTE_UNUSED, void *data) types, so we have to do our own traversals here. */ add_tree_to_fld_list (t, fld); - walk_tree (&TYPE_CACHED_VALUES (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_SIZE (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_SIZE_UNIT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_ATTRIBUTES (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_POINTER_TO (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_REFERENCE_TO (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_NAME (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_MINVAL (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_MAXVAL (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_NEXT_VARIANT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_MAIN_VARIANT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_CONTEXT (t), find_decls_types_r, fld, fld->pset); - walk_tree (&TYPE_CANONICAL (t), find_decls_types_r, fld, fld->pset); - } - - if (TREE_TYPE (t)) - walk_tree (&TREE_TYPE (t), find_decls_types_r, fld, fld->pset); + PUSH (TYPE_CACHED_VALUES (t)); + PUSH (TYPE_SIZE (t)); + PUSH (TYPE_SIZE_UNIT (t)); + PUSH (TYPE_ATTRIBUTES (t)); + PUSH (TYPE_POINTER_TO (t)); + PUSH (TYPE_REFERENCE_TO (t)); + PUSH (TYPE_NAME (t)); + PUSH (TYPE_MINVAL (t)); + PUSH (TYPE_MAXVAL (t)); + PUSH (TYPE_MAIN_VARIANT (t)); + PUSH (TYPE_NEXT_VARIANT (t)); + PUSH (TYPE_CONTEXT (t)); + PUSH (TYPE_CANONICAL (t)); + + if (RECORD_OR_UNION_TYPE_P (t) + && TYPE_BINFO (t)) + { + unsigned i; + tree tem; + for (i = 0; VEC_iterate (tree, BINFO_BASE_BINFOS (TYPE_BINFO (t)), + i, tem); ++i) + PUSH (TREE_TYPE (tem)); + } - /* Do not recurse into TREE_CHAIN to avoid blowing up the stack. */ - for (tp = &TREE_CHAIN (t); *tp; tp = &TREE_CHAIN (*tp)) - { - tree saved_chain = TREE_CHAIN (*tp); - TREE_CHAIN (*tp) = NULL_TREE; - walk_tree (tp, find_decls_types_r, fld, fld->pset); - TREE_CHAIN (*tp) = saved_chain; + PUSH (TREE_CHAIN (t)); + *ws = 0; } + PUSH (TREE_TYPE (t)); + return NULL_TREE; } +#undef PUSH + +/* Find decls and types in T. */ + +static void +find_decls_types (tree t, struct free_lang_data_d *fld) +{ + while (1) + { + if (!pointer_set_contains (fld->pset, t)) + walk_tree (&t, find_decls_types_r, fld, fld->pset); + if (VEC_empty (tree, fld->worklist)) + break; + t = VEC_pop (tree, fld->worklist); + } +} /* Translate all the types in LIST with the corresponding runtime types. */ @@ -4641,13 +4677,13 @@ find_decls_types_in_eh_region (eh_region r, struct free_lang_data_d *fld) { tree list = r->u.eh_catch.type_list; r->u.eh_catch.type_list = get_eh_types_for_runtime (list); - walk_tree (&r->u.eh_catch.type_list, find_decls_types_r, fld, fld->pset); + find_decls_types (r->u.eh_catch.type_list, fld); } else if (r->type == ERT_ALLOWED_EXCEPTIONS) { tree list = r->u.allowed.type_list; r->u.allowed.type_list = get_eh_types_for_runtime (list); - walk_tree (&r->u.allowed.type_list, find_decls_types_r, fld, fld->pset); + find_decls_types (r->u.allowed.type_list, fld); } } @@ -4665,7 +4701,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) struct function *fn; tree t; - walk_tree (&n->decl, find_decls_types_r, fld, fld->pset); + find_decls_types (n->decl, fld); if (!gimple_has_body_p (n->decl)) return; @@ -4676,13 +4712,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) /* Traverse locals. */ for (t = fn->local_decls; t; t = TREE_CHAIN (t)) - { - tree *tp = &TREE_VALUE (t); - tree saved_chain = TREE_CHAIN (*tp); - TREE_CHAIN (*tp) = NULL_TREE; - walk_tree (tp, find_decls_types_r, fld, fld->pset); - TREE_CHAIN (*tp) = saved_chain; - } + find_decls_types (TREE_VALUE (t), fld); /* Traverse EH regions in FN. */ if (fn->eh->region_array) @@ -4707,7 +4737,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) for (i = 0; i < gimple_phi_num_args (phi); i++) { tree *arg_p = gimple_phi_arg_def_ptr (phi, i); - walk_tree (arg_p, find_decls_types_r, fld, fld->pset); + find_decls_types (*arg_p, fld); } } @@ -4717,8 +4747,8 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) for (i = 0; i < gimple_num_ops (stmt); i++) { - tree *arg_p = gimple_op_ptr (stmt, i); - walk_tree (arg_p, find_decls_types_r, fld, fld->pset); + tree arg = gimple_op (stmt, i); + find_decls_types (arg, fld); } } } @@ -4734,7 +4764,7 @@ find_decls_types_in_node (struct cgraph_node *n, struct free_lang_data_d *fld) static void find_decls_types_in_var (struct varpool_node *v, struct free_lang_data_d *fld) { - walk_tree (&v->decl, find_decls_types_r, fld, fld->pset); + find_decls_types (v->decl, fld); } @@ -4767,6 +4797,7 @@ free_lang_data_in_cgraph (void) /* Initialize sets and arrays to store referenced decls and types. */ fld.pset = pointer_set_create (); + fld.worklist = NULL; fld.decls = VEC_alloc (tree, heap, 100); fld.types = VEC_alloc (tree, heap, 100); @@ -4775,7 +4806,7 @@ free_lang_data_in_cgraph (void) find_decls_types_in_node (n, &fld); for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); i++) - walk_tree (&p->decl, find_decls_types_r, &fld, fld.pset); + find_decls_types (p->decl, &fld); /* Find decls and types in every varpool symbol. */ for (v = varpool_nodes_queue; v; v = v->next_needed) @@ -4815,6 +4846,7 @@ free_lang_data_in_cgraph (void) free_lang_data_in_type (t); pointer_set_destroy (fld.pset); + VEC_free (tree, heap, fld.worklist); VEC_free (tree, heap, fld.decls); VEC_free (tree, heap, fld.types); } @@ -10534,5 +10566,20 @@ tree_strip_sign_nop_conversions (tree exp) return exp; } +static GTY(()) tree gcc_eh_personality_decl; + +/* Return the GCC personality function decl. */ + +tree +lhd_gcc_personality (void) +{ + if (!gcc_eh_personality_decl) + gcc_eh_personality_decl + = build_personality_function (USING_SJLJ_EXCEPTIONS + ? "__gcc_personality_sj0" + : "__gcc_personality_v0"); + + return gcc_eh_personality_decl; +} #include "gt-tree.h" diff --git a/gcc/tree.h b/gcc/tree.h index 59251b58d14..5884b55a0b6 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1065,12 +1065,17 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, (SCALAR_FLOAT_TYPE_P (TYPE) \ && DECIMAL_FLOAT_MODE_P (TYPE_MODE (TYPE))) +/* Nonzero if TYPE is a record or union type. */ +#define RECORD_OR_UNION_TYPE_P(TYPE) \ + (TREE_CODE (TYPE) == RECORD_TYPE \ + || TREE_CODE (TYPE) == UNION_TYPE \ + || TREE_CODE (TYPE) == QUAL_UNION_TYPE) + /* Nonzero if TYPE represents an aggregate (multi-component) type. Keep these checks in ascending code order. */ #define AGGREGATE_TYPE_P(TYPE) \ - (TREE_CODE (TYPE) == ARRAY_TYPE || TREE_CODE (TYPE) == RECORD_TYPE \ - || TREE_CODE (TYPE) == UNION_TYPE || TREE_CODE (TYPE) == QUAL_UNION_TYPE) + (TREE_CODE (TYPE) == ARRAY_TYPE || RECORD_OR_UNION_TYPE_P (TYPE)) /* Nonzero if TYPE represents a pointer or reference type. (It should be renamed to INDIRECT_TYPE_P.) Keep these checks in @@ -2533,8 +2538,12 @@ struct GTY(()) tree_decl_minimal { #define DECL_DEBUG_EXPR_IS_FROM(NODE) \ (DECL_COMMON_CHECK (NODE)->decl_common.debug_expr_is_from) +#define DECL_FUNCTION_PERSONALITY(NODE) \ + (FUNCTION_DECL_CHECK (NODE)->function_decl.personality) + /* Nonzero for a given ..._DECL node means that the name of this node should - be ignored for symbolic debug purposes. */ + be ignored for symbolic debug purposes. Moreover, for a FUNCTION_DECL, + the body of the function should also be ignored. */ #define DECL_IGNORED_P(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.ignored_flag) /* Nonzero for a given ..._DECL node means that this node represents an @@ -2647,15 +2656,16 @@ struct GTY(()) tree_decl_common { /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */ unsigned int off_align : 8; + /* 24-bits unused. */ + + /* DECL_ALIGN. It should have the same size as TYPE_ALIGN. */ + unsigned int align; + tree size_unit; tree initial; tree attributes; tree abstract_origin; - /* DECL_ALIGN. It should have the same size as TYPE_ALIGN. */ - unsigned int align; - - int label_decl_uid; /* Points to a structure whose details depend on the language in use. */ struct lang_decl *lang_specific; }; @@ -2778,21 +2788,22 @@ struct GTY(()) tree_field_decl { tree qualifier; tree bit_offset; tree fcontext; - }; /* A numeric unique identifier for a LABEL_DECL. The UID allocation is dense, unique within any one function, and may be used to index arrays. If the value is -1, then no UID has been assigned. */ #define LABEL_DECL_UID(NODE) \ - (LABEL_DECL_CHECK (NODE)->decl_common.label_decl_uid) + (LABEL_DECL_CHECK (NODE)->label_decl.label_decl_uid) /* In LABEL_DECL nodes, nonzero means that an error message about jumping into such a binding contour has been printed for this label. */ -#define DECL_ERROR_ISSUED(NODE) (LABEL_DECL_CHECK (NODE)->decl_common.decl_flag_0) +#define DECL_ERROR_ISSUED(NODE) \ + (LABEL_DECL_CHECK (NODE)->decl_common.decl_flag_0) struct GTY(()) tree_label_decl { struct tree_decl_with_rtl common; + int label_decl_uid; }; struct GTY(()) tree_result_decl { @@ -3183,6 +3194,9 @@ struct GTY(()) tree_function_decl { struct function *f; + /* The personality function. Used for stack unwinding. */ + tree personality; + /* Function specific options that are used by this function. */ tree function_specific_target; /* target options */ tree function_specific_optimization; /* optimization options */ @@ -3907,6 +3921,7 @@ extern bool range_in_array_bounds_p (tree); extern tree value_member (tree, tree); extern tree purpose_member (const_tree, tree); +extern tree chain_index (int, tree); extern int attribute_list_equal (const_tree, const_tree); extern int attribute_list_contained (const_tree, const_tree); @@ -4644,6 +4659,7 @@ extern bool auto_var_in_fn_p (const_tree, const_tree); extern tree build_low_bits_mask (tree, unsigned); extern tree tree_strip_nop_conversions (tree); extern tree tree_strip_sign_nop_conversions (tree); +extern tree lhd_gcc_personality (void); /* In cgraph.c */ extern void change_decl_assembler_name (tree, tree); @@ -5255,6 +5271,7 @@ extern unsigned HOST_WIDE_INT compute_builtin_object_size (tree, int); /* In expr.c. */ extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree); +extern tree build_personality_function (const char *); /* In tree-inline.c. */ diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 475ba57553e..0e665b91bed 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -6243,7 +6243,8 @@ check_wrap_constant (enum machine_mode mode, rtx result) } /* Callback for cselib_expand_value, that looks for expressions - holding the value in the var-tracking hash tables. */ + holding the value in the var-tracking hash tables. Return X for + standard processing, anything else is to be used as-is. */ static rtx vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data) @@ -6254,19 +6255,46 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data) location_chain loc; rtx result; - gcc_assert (GET_CODE (x) == VALUE); + if (GET_CODE (x) == SUBREG) + { + rtx subreg = SUBREG_REG (x); + + if (GET_CODE (SUBREG_REG (x)) != VALUE) + return x; + + subreg = cselib_expand_value_rtx_cb (SUBREG_REG (x), regs, + max_depth - 1, + vt_expand_loc_callback, data); + + if (!subreg) + return NULL; + + result = simplify_gen_subreg (GET_MODE (x), subreg, + GET_MODE (SUBREG_REG (x)), + SUBREG_BYTE (x)); + + /* Invalid SUBREGs are ok in debug info. ??? We could try + alternate expansions for the VALUE as well. */ + if (!result && (REG_P (subreg) || MEM_P (subreg))) + result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x)); + + return result; + } + + if (GET_CODE (x) != VALUE) + return x; if (VALUE_RECURSED_INTO (x)) - return NULL; + return x; dv = dv_from_value (x); var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv)); if (!var) - return NULL; + return x; if (var->n_var_parts == 0) - return NULL; + return x; gcc_assert (var->n_var_parts == 1); @@ -6283,7 +6311,10 @@ vt_expand_loc_callback (rtx x, bitmap regs, int max_depth, void *data) } VALUE_RECURSED_INTO (x) = false; - return result; + if (result) + return result; + else + return x; } /* Expand VALUEs in LOC, using VARS as well as cselib's equivalence diff --git a/gcc/varasm.c b/gcc/varasm.c index a7fa83fc107..f8cc2914693 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -1749,7 +1749,8 @@ assemble_start_function (tree decl, const char *fnname) ASM_OUTPUT_FUNCTION_PREFIX (asm_out_file, fnname); #endif - (*debug_hooks->begin_function) (decl); + if (!DECL_IGNORED_P (decl)) + (*debug_hooks->begin_function) (decl); /* Make function name accessible from other files, if appropriate. */ diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 1b020ac0ab8..5d278223113 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,13 @@ +2009-09-13 Kai Tietz <kai.tietz@onevision.com> + + * configure.ac: Set for i?86-w64-mingw* + need_64bit_hwint to yes. + * configure: Regenerated. + +2009-09-10 Jason Merrill <jason@redhat.com> + + * directives.c (cpp_define): constify. + 2009-09-02 Ian Lance Taylor <iant@google.com> * macro.c (stringify_arg): Escape CPP_WCHAR tokens. diff --git a/libcpp/configure b/libcpp/configure index 80249e76925..eaf99dd28d6 100755 --- a/libcpp/configure +++ b/libcpp/configure @@ -6876,6 +6876,7 @@ case $target in hppa*64*-*-* | \ i[34567]86-*-darwin* | \ i[34567]86-*-solaris2.1[0-9]* | \ + i[34567]86-w64-mingw* | \ mips*-*-* | \ mmix-*-* | \ powerpc*-*-* | \ diff --git a/libcpp/configure.ac b/libcpp/configure.ac index 3af4e166e71..52465462165 100644 --- a/libcpp/configure.ac +++ b/libcpp/configure.ac @@ -146,6 +146,7 @@ case $target in hppa*64*-*-* | \ i[34567]86-*-darwin* | \ i[34567]86-*-solaris2.1[0-9]* | \ + i[34567]86-w64-mingw* | \ mips*-*-* | \ mmix-*-* | \ powerpc*-*-* | \ diff --git a/libcpp/directives.c b/libcpp/directives.c index 9c988dfa136..c5a1895b86e 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -2156,7 +2156,8 @@ do_unassert (cpp_reader *pfile) void cpp_define (cpp_reader *pfile, const char *str) { - char *buf, *p; + char *buf; + const char *p; size_t count; /* Copy the entire option so we can modify it. diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index f46f11a861e..346981415f1 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,19 @@ +2009-09-12 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libgfortran/41328 + * io/transfer.c (read_sf): Adjust fbuf position and do proper + fbuf reads to traverse CR, CR-LF, and LF style line ends. + +2009-09-12 Jerry DeLisle <jvdelisle@gcc.gnu.org> + + PR libgfortran/41219 + * io/write.c (write_a_char4): Use correct type for crlf constant. + +2009-09-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.am (libgfortranbegin_la_LINK): New. + * Makefile.in: Regenerate. + 2009-09-09 Paolo Bonzini <bonzini@gnu.org> * configure: Regenerate. diff --git a/libgfortran/Makefile.am b/libgfortran/Makefile.am index 08609557ce6..c2fd941a992 100644 --- a/libgfortran/Makefile.am +++ b/libgfortran/Makefile.am @@ -24,6 +24,7 @@ myexeclib_LTLIBRARIES = libgfortranbegin.la myexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR) libgfortranbegin_la_SOURCES = fmain.c libgfortranbegin_la_LDFLAGS = -static +libgfortranbegin_la_LINK = $(LINK) $(libgfortranbegin_la_LDFLAGS) ## io.h conflicts with a system header on some platforms, so ## use -iquote diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in index 1bcae42d52d..462b07b487b 100644 --- a/libgfortran/Makefile.in +++ b/libgfortran/Makefile.in @@ -777,9 +777,6 @@ libgfortran_la_OBJECTS = $(am_libgfortran_la_OBJECTS) libgfortranbegin_la_LIBADD = am_libgfortranbegin_la_OBJECTS = fmain.lo libgfortranbegin_la_OBJECTS = $(am_libgfortranbegin_la_OBJECTS) -libgfortranbegin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libgfortranbegin_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/../depcomp am__depfiles_maybe = depfiles @@ -984,6 +981,7 @@ myexeclib_LTLIBRARIES = libgfortranbegin.la myexeclibdir = $(libdir)/gcc/$(target_alias)/$(gcc_version)$(MULTISUBDIR) libgfortranbegin_la_SOURCES = fmain.c libgfortranbegin_la_LDFLAGS = -static +libgfortranbegin_la_LINK = $(LINK) $(libgfortranbegin_la_LDFLAGS) AM_CPPFLAGS = -iquote$(srcdir)/io -I$(srcdir)/$(MULTISRCTOP)../gcc \ -I$(srcdir)/$(MULTISRCTOP)../gcc/config \ -I$(MULTIBUILDTOP)../../$(host_subdir)/gcc -D_GNU_SOURCE diff --git a/libgfortran/io/transfer.c b/libgfortran/io/transfer.c index 59f88d4fb9b..2362a154592 100644 --- a/libgfortran/io/transfer.c +++ b/libgfortran/io/transfer.c @@ -232,21 +232,28 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error) if (q == '\n' || q == '\r') { - /* Unexpected end of line. */ + /* Unexpected end of line. Set the position. */ + fbuf_seek (dtp->u.p.current_unit, n + 1 ,SEEK_CUR); + dtp->u.p.sf_seen_eor = 1; /* If we see an EOR during non-advancing I/O, we need to skip the rest of the I/O statement. Set the corresponding flag. */ if (dtp->u.p.advance_status == ADVANCE_NO || dtp->u.p.seen_dollar) dtp->u.p.eor_condition = 1; - + /* If we encounter a CR, it might be a CRLF. */ if (q == '\r') /* Probably a CRLF */ { - if (n < *length && *(p + 1) == '\n') - dtp->u.p.sf_seen_eor = 2; + /* See if there is an LF. Use fbuf_read rather then fbuf_getc so + the position is not advanced unless it really is an LF. */ + int readlen = 1; + p = fbuf_read (dtp->u.p.current_unit, &readlen); + if (*p == '\n' && readlen == 1) + { + dtp->u.p.sf_seen_eor = 2; + fbuf_seek (dtp->u.p.current_unit, 1 ,SEEK_CUR); + } } - else - dtp->u.p.sf_seen_eor = 1; /* Without padding, terminate the I/O statement without assigning the value. With padding, the value still needs to be assigned, @@ -260,7 +267,7 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error) } *length = n; - break; + goto done; } /* Short circuit the read if a comma is found during numeric input. The flag is set to zero during character reads so that commas in @@ -274,13 +281,11 @@ read_sf (st_parameter_dt *dtp, int * length, int no_error) *length = n; break; } - n++; p++; } - fbuf_seek (dtp->u.p.current_unit, n + dtp->u.p.sf_seen_eor + seen_comma, - SEEK_CUR); + fbuf_seek (dtp->u.p.current_unit, n + seen_comma, SEEK_CUR); /* A short read implies we hit EOF, unless we hit EOR, a comma, or some other stuff. Set the relevant flags. */ diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c index 4956da8cf80..3c16a43b9ab 100644 --- a/libgfortran/io/write.c +++ b/libgfortran/io/write.c @@ -293,7 +293,7 @@ write_a_char4 (st_parameter_dt *dtp, const fnode *f, const char *source, int len Standard sections 10.6.3 and 9.9 for further information. */ if (is_stream_io (dtp)) { - const char crlf[] = "\r\n"; + const gfc_char4_t crlf[] = {0x000d,0x000a}; int i, bytes; gfc_char4_t *qq; bytes = 0; diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index e88bdee68ad..d94cb78d24c 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,8 @@ +2009-09-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.am (libgomp_la_LINK): New. + * Makefile.in: Regenerate. + 2009-08-24 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> * configure.ac (AC_PREREQ): Bump to 2.64. diff --git a/libgomp/Makefile.am b/libgomp/Makefile.am index 5bc0732c01f..3786bee4c13 100644 --- a/libgomp/Makefile.am +++ b/libgomp/Makefile.am @@ -29,6 +29,7 @@ endif libgomp_version_info = -version-info $(libtool_VERSION) libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \ -no-undefined -bindir "$(bindir)" +libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS) libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \ iter_ull.c loop.c loop_ull.c ordered.c parallel.c sections.c single.c \ diff --git a/libgomp/Makefile.in b/libgomp/Makefile.in index d5b9c474904..20c6975833e 100644 --- a/libgomp/Makefile.in +++ b/libgomp/Makefile.in @@ -100,9 +100,6 @@ am_libgomp_la_OBJECTS = alloc.lo barrier.lo critical.lo env.lo \ lock.lo mutex.lo proc.lo sem.lo bar.lo ptrlock.lo time.lo \ fortran.lo affinity.lo libgomp_la_OBJECTS = $(am_libgomp_la_OBJECTS) -libgomp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(libgomp_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/../depcomp am__depfiles_maybe = depfiles @@ -347,6 +344,7 @@ libgomp_version_info = -version-info $(libtool_VERSION) libgomp_la_LDFLAGS = $(libgomp_version_info) $(libgomp_version_script) \ -no-undefined -bindir "$(bindir)" +libgomp_la_LINK = $(LINK) $(libgomp_la_LDFLAGS) libgomp_la_SOURCES = alloc.c barrier.c critical.c env.c error.c iter.c \ iter_ull.c loop.c loop_ull.c ordered.c parallel.c sections.c single.c \ task.c team.c work.c lock.c mutex.c proc.c sem.c bar.c ptrlock.c \ diff --git a/libjava/ChangeLog b/libjava/ChangeLog index be89f186885..829023209cb 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,8 @@ +2009-09-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * Makefile.am (libgij_la_LINK, libjvm_la_LINK): New. + * Makefile.in: Regenerate. + 2009-09-08 Alexandre Oliva <aoliva@redhat.com> * configure: Rebuilt with modified libtool.m4. diff --git a/libjava/Makefile.am b/libjava/Makefile.am index 13b25ac7ea6..7b6750c493c 100644 --- a/libjava/Makefile.am +++ b/libjava/Makefile.am @@ -223,6 +223,7 @@ libgij_la_LIBADD = -L$(here)/.libs libgcj.la ## The mysterious backslash in the grep pattern is consumed by make. libgij_la_LDFLAGS = -rpath $(toolexeclibdir) \ -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LIBGCJ_LD_SYMBOLIC) +libgij_la_LINK = $(CXXLINK) $(libgij_la_LDFLAGS) if INTERPRETER libgcj_interpret_source_files = jvmti.cc interpret.cc @@ -326,6 +327,7 @@ libjvm_la_DEPENDENCIES = libgcj.la libgcj.spec ## See jv_convert_LDADD. libjvm_la_LIBADD = -L$(here)/.libs libgcj.la libjvm_la_LDFLAGS = -avoid-version $(LIBGCJ_LD_SYMBOLIC) +libjvm_la_LINK = $(CXXLINK) $(libjvm_la_LDFLAGS) ## The .db file. This rule is only used for native builds, so it is ## safe to invoke gcj-dbtool. diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 9608e7941df..349b9074d34 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -454,14 +454,8 @@ libgcj_bc_la_OBJECTS = $(am_libgcj_bc_la_OBJECTS) @USE_LIBGCJ_BC_TRUE@am_libgcj_bc_la_rpath = -rpath $(toolexeclibdir) am_libgij_la_OBJECTS = gij.lo libgij_la_OBJECTS = $(am_libgij_la_OBJECTS) -libgij_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(libgij_la_LDFLAGS) $(LDFLAGS) -o $@ am_libjvm_la_OBJECTS = jni-libjvm.lo libjvm_la_OBJECTS = $(am_libjvm_la_OBJECTS) -libjvm_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(libjvm_la_LDFLAGS) $(LDFLAGS) -o $@ @CREATE_GJDOC_TRUE@@NATIVE_TRUE@am__EXEEXT_1 = gjdoc$(EXEEXT) @NATIVE_TRUE@am__EXEEXT_2 = jv-convert$(EXEEXT) gij$(EXEEXT) \ @NATIVE_TRUE@ grmic$(EXEEXT) grmiregistry$(EXEEXT) \ @@ -973,6 +967,7 @@ libgij_la_LIBADD = -L$(here)/.libs libgcj.la libgij_la_LDFLAGS = -rpath $(toolexeclibdir) \ -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LIBGCJ_LD_SYMBOLIC) +libgij_la_LINK = $(CXXLINK) $(libgij_la_LDFLAGS) @INTERPRETER_FALSE@libgcj_interpret_source_files = @INTERPRETER_TRUE@libgcj_interpret_source_files = jvmti.cc interpret.cc libgcj_la_SOURCES = prims.cc jni.cc exception.cc stacktrace.cc link.cc \ @@ -1027,6 +1022,7 @@ libjvm_la_SOURCES = jni-libjvm.cc libjvm_la_DEPENDENCIES = libgcj.la libgcj.spec libjvm_la_LIBADD = -L$(here)/.libs libgcj.la libjvm_la_LDFLAGS = -avoid-version $(LIBGCJ_LD_SYMBOLIC) +libjvm_la_LINK = $(CXXLINK) $(libjvm_la_LDFLAGS) lib_gnu_awt_xlib_la_SOURCES = $(xlib_nat_source_files) lib_gnu_awt_xlib_la_LIBADD = gnu/awt/xlib.lo gnu/gcj/xlib.lo lib_gnu_awt_xlib_la_DEPENDENCIES = libgcj-$(gcc_version).jar \ diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 7f646a97526..8cb9560b54f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,35 @@ +2009-09-11 Johannes Singler <singler@ira.uka.de> + + * include/parallel/multiway_merge.h + (multiway_merge_exact_splitting): Deallocate borders correctly. + (parallel_multiway_merge): Remove unnecessarily complicated + allocation, random access iterators are default-constructible; + deallocate ne_seqs correctly. + +2009-09-11 Paolo Carlini <paolo.carlini@oracle.com> + + PR libstdc++/41316 + * include/bits/forward_list.h (_Fwd_list_node_base<>::_M_sort_after): + Remove. + (forward_list<>::sort(_Comp)): Only declare. + (forward_list<>::sort()): Forward to the latter. + * include/bits/forward_list.tcc (_Fwd_list_node_base<>::_M_sort_after): + Remove definition. + (forward_list<>::sort(_Comp)): Define. + * testsuite/23_containers/forward_list/requirements/dr438/ + assign_neg.cc: Adjust dg-error line number. + * testsuite/23_containers/forward_list/requirements/dr438/ + insert_neg.cc: Likewise. + * testsuite/23_containers/forward_list/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/forward_list/requirements/dr438/ + constructor_2_neg.cc: Likewise. + +2009-09-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> + + * src/Makefile.am (libstdc___la_LINK): New. + * src/Makefile.in: Regenerate. + 2009-09-09 Loren J. Rittle <ljrittle@acm.org> * testsuite/30_threads/thread/native_handle/typesizes.cc: Remove diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index 5158f2dac64..0ec5a1141a9 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -92,10 +92,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) : _Fwd_list_node_base<_Alloc>(), _M_value(std::forward<_Args>(__args)...) { } - template<typename _Comp> - void - _M_sort_after(_Comp __comp); - _Tp _M_value; }; @@ -1149,7 +1145,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ void merge(forward_list&& __list) - { this->merge(std::forward<forward_list>(__list), std::less<_Tp>()); } + { this->merge(std::move(__list), std::less<_Tp>()); } /** * @brief Merge sorted lists according to comparison function. @@ -1174,10 +1170,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ void sort() - { - _Node* __tmp = __static_pointer_cast<_Node*>(&this->_M_impl._M_head); - __tmp->_M_sort_after(std::less<_Tp>()); - } + { this->sort(std::less<_Tp>()); } /** * @brief Sort the forward_list using a comparison function. @@ -1187,11 +1180,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) */ template<typename _Comp> void - sort(_Comp __comp) - { - _Node* __tmp = __static_pointer_cast<_Node*>(&this->_M_impl._M_head); - __tmp->_M_sort_after(__comp); - } + sort(_Comp __comp); /** * @brief Reverse the elements in list. @@ -1285,7 +1274,7 @@ _GLIBCXX_BEGIN_NAMESPACE(std) template<typename _Tp, typename _Alloc> inline void swap(forward_list<_Tp, _Alloc>& __lx, - forward_list<_Tp, _Alloc>& __ly) + forward_list<_Tp, _Alloc>& __ly) { __lx.swap(__ly); } _GLIBCXX_END_NAMESPACE // namespace std diff --git a/libstdc++-v3/include/bits/forward_list.tcc b/libstdc++-v3/include/bits/forward_list.tcc index 8458e7e5fee..13573699061 100644 --- a/libstdc++-v3/include/bits/forward_list.tcc +++ b/libstdc++-v3/include/bits/forward_list.tcc @@ -75,111 +75,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) } } - /** - * @brief Sort the singly linked list starting after this node. - * This node is assumed to be an empty head node (of type - * _Fwd_list_node_base). - */ - template<typename _Tp, class _Alloc> - template<typename _Comp> - void - _Fwd_list_node<_Tp, _Alloc>:: - _M_sort_after(_Comp __comp) - { - // If `next' is 0, return immediately. - _Pointer __list = __static_pointer_cast<_Pointer>(this->_M_next); - if (!__list) - return; - - unsigned long __insize = 1; - - while (1) - { - _Pointer __p = __list; - __list = 0; - _Pointer __tail = 0; - - // Count number of merges we do in this pass. - unsigned long __nmerges = 0; - - while (__p) - { - ++__nmerges; - // There exists a merge to be done. - // Step `insize' places along from p. - _Pointer __q = __p; - unsigned long __psize = 0; - for (unsigned long __i = 0; __i < __insize; ++__i) - { - ++__psize; - __q = __static_pointer_cast<_Pointer>(__q->_M_next); - if (!__q) - break; - } - - // If q hasn't fallen off end, we have two lists to merge. - unsigned long __qsize = __insize; - - // Now we have two lists; merge them. - while (__psize > 0 || (__qsize > 0 && __q)) - { - // Decide whether next node of merge comes from p or q. - _Pointer __e; - if (__psize == 0) - { - // p is empty; e must come from q. - __e = __q; - __q = __static_pointer_cast<_Pointer>(__q->_M_next); - --__qsize; - } - else if (__qsize == 0 || !__q) - { - // q is empty; e must come from p. - __e = __p; - __p = __static_pointer_cast<_Pointer>(__p->_M_next); - --__psize; - } - else if (__comp(__p->_M_value, __q->_M_value)) - { - // First node of p is lower; e must come from p. - __e = __p; - __p = __static_pointer_cast<_Pointer>(__p->_M_next); - --__psize; - } - else - { - // First node of q is lower; e must come from q. - __e = __q; - __q = __static_pointer_cast<_Pointer>(__q->_M_next); - --__qsize; - } - - // Add the next node to the merged list. - if (__tail) - __tail->_M_next = __e; - else - __list = __e; - __tail = __e; - } - - // Now p has stepped `insize' places along, and q has too. - __p = __q; - } - __tail->_M_next = 0; - - // If we have done only one merge, we're finished. - // Allow for nmerges == 0, the empty list case. - if (__nmerges <= 1) - { - this->_M_next = __list; - return; - } - - // Otherwise repeat, merging lists twice the size. - __insize *= 2; - } - } - template<typename _Tp, typename _Alloc> _Fwd_list_base<_Tp, _Alloc>:: _Fwd_list_base(const _Fwd_list_base& __lst, const _Alloc& __a) @@ -472,6 +367,109 @@ _GLIBCXX_BEGIN_NAMESPACE(std) return false; } + template<typename _Tp, class _Alloc> + template<typename _Comp> + void + forward_list<_Tp, _Alloc>:: + sort(_Comp __comp) + { + typedef typename _Node::_Pointer _Pointer; + + // If `next' is 0, return immediately. + _Pointer __list = + __static_pointer_cast<_Pointer>(this->_M_impl._M_head._M_next); + if (!__list) + return; + + unsigned long __insize = 1; + + while (1) + { + _Pointer __p = __list; + __list = 0; + _Pointer __tail = 0; + + // Count number of merges we do in this pass. + unsigned long __nmerges = 0; + + while (__p) + { + ++__nmerges; + // There exists a merge to be done. + // Step `insize' places along from p. + _Pointer __q = __p; + unsigned long __psize = 0; + for (unsigned long __i = 0; __i < __insize; ++__i) + { + ++__psize; + __q = __static_pointer_cast<_Pointer>(__q->_M_next); + if (!__q) + break; + } + + // If q hasn't fallen off end, we have two lists to merge. + unsigned long __qsize = __insize; + + // Now we have two lists; merge them. + while (__psize > 0 || (__qsize > 0 && __q)) + { + // Decide whether next node of merge comes from p or q. + _Pointer __e; + if (__psize == 0) + { + // p is empty; e must come from q. + __e = __q; + __q = __static_pointer_cast<_Pointer>(__q->_M_next); + --__qsize; + } + else if (__qsize == 0 || !__q) + { + // q is empty; e must come from p. + __e = __p; + __p = __static_pointer_cast<_Pointer>(__p->_M_next); + --__psize; + } + else if (__comp(__p->_M_value, __q->_M_value)) + { + // First node of p is lower; e must come from p. + __e = __p; + __p = __static_pointer_cast<_Pointer>(__p->_M_next); + --__psize; + } + else + { + // First node of q is lower; e must come from q. + __e = __q; + __q = __static_pointer_cast<_Pointer>(__q->_M_next); + --__qsize; + } + + // Add the next node to the merged list. + if (__tail) + __tail->_M_next = __e; + else + __list = __e; + __tail = __e; + } + + // Now p has stepped `insize' places along, and q has too. + __p = __q; + } + __tail->_M_next = 0; + + // If we have done only one merge, we're finished. + // Allow for nmerges == 0, the empty list case. + if (__nmerges <= 1) + { + this->_M_impl._M_head._M_next = __list; + return; + } + + // Otherwise repeat, merging lists twice the size. + __insize *= 2; + } + } + _GLIBCXX_END_NAMESPACE // namespace std #endif /* _FORWARD_LIST_TCC */ diff --git a/libstdc++-v3/include/parallel/multiway_merge.h b/libstdc++-v3/include/parallel/multiway_merge.h index bacff8dbadb..fe32053d6c1 100644 --- a/libstdc++-v3/include/parallel/multiway_merge.h +++ b/libstdc++-v3/include/parallel/multiway_merge.h @@ -1224,7 +1224,7 @@ void multiway_merge_exact_splitting( offsets[num_threads - 1].begin(), comp); } } - + delete[] borders; for (int slab = 0; slab < num_threads; ++slab) { @@ -1305,11 +1305,8 @@ template< std::iterator_traits<RandomAccessIterator1>::value_type value_type; // Leave only non-empty sequences. - std::pair<RandomAccessIterator1, RandomAccessIterator1>* ne_seqs = - static_cast<std::pair<RandomAccessIterator1, RandomAccessIterator1>*>( - ::operator new( - sizeof(std::pair<RandomAccessIterator1, RandomAccessIterator1>) - * (seqs_end - seqs_begin))); + typedef std::pair<RandomAccessIterator1, RandomAccessIterator1> seq_type; + seq_type* ne_seqs = new seq_type[seqs_end - seqs_begin]; int k = 0; difference_type total_length = 0; for (RandomAccessIteratorIterator raii = seqs_begin; @@ -1319,9 +1316,7 @@ template< if(seq_length > 0) { total_length += seq_length; - //ne_seqs[k] = *raii; - new(&(ne_seqs[k++])) - std::pair<RandomAccessIterator1, RandomAccessIterator1>(*raii); + ne_seqs[k++] = *raii; } } @@ -1331,7 +1326,7 @@ template< if (total_length == 0 || k == 0) { - ::operator delete(ne_seqs); + delete[] ne_seqs; return target; } @@ -1366,8 +1361,7 @@ template< for (int c = 0; c < k; ++c) target_position += pieces[iam][c].first; - std::pair<RandomAccessIterator1, RandomAccessIterator1>* chunks - = new std::pair<RandomAccessIterator1, RandomAccessIterator1>[k]; + seq_type* chunks = new seq_type[k]; for (int s = 0; s < k; ++s) { @@ -1399,6 +1393,7 @@ template< } delete[] pieces; + delete[] ne_seqs; return target + length; } diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am index 54d521825c4..9513bd52dbf 100644 --- a/libstdc++-v3/src/Makefile.am +++ b/libstdc++-v3/src/Makefile.am @@ -209,6 +209,8 @@ libstdc___la_DEPENDENCIES = \ libstdc___la_LDFLAGS = \ -version-info $(libtool_VERSION) ${version_arg} -lm +libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS) + # Use special rules for the deprecated source files so that they find # deprecated include files. GLIBCXX_INCLUDE_DIR=$(glibcxx_builddir)/include diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in index e484d86e130..9c03ac4dc78 100644 --- a/libstdc++-v3/src/Makefile.in +++ b/libstdc++-v3/src/Makefile.in @@ -129,9 +129,6 @@ am__objects_5 = atomic.lo bitmap_allocator.lo pool_allocator.lo \ thread.lo future.lo $(am__objects_1) $(am__objects_4) am_libstdc___la_OBJECTS = $(am__objects_5) libstdc___la_OBJECTS = $(am_libstdc___la_OBJECTS) -libstdc___la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ - $(CXXFLAGS) $(libstdc___la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = am__depfiles_maybe = @@ -450,6 +447,7 @@ libstdc___la_DEPENDENCIES = \ libstdc___la_LDFLAGS = \ -version-info $(libtool_VERSION) ${version_arg} -lm +libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS) # Use special rules for the deprecated source files so that they find # deprecated include files. diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc index 93f0e6d591d..5062ddfa234 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1209 } +// { dg-error "no matching" "" { target *-*-* } 1198 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc index 70d0447a5d6..6347d964a46 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1209 } +// { dg-error "no matching" "" { target *-*-* } 1198 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc index 2ee8b9f6baf..af668527dfb 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1209 } +// { dg-error "no matching" "" { target *-*-* } 1198 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc index a21c22242b3..bc8a62d54ab 100644 --- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc @@ -1,6 +1,6 @@ // { dg-do compile } // { dg-options "-std=gnu++0x" } -// { dg-error "no matching" "" { target *-*-* } 1209 } +// { dg-error "no matching" "" { target *-*-* } 1198 } // { dg-excess-errors "" } // Copyright (C) 2009 Free Software Foundation |